Componentes.Terceros.DevExp.../official/x.44/ExpressLayout Control 2/Sources/dxLayoutControl.pas

11532 lines
337 KiB
ObjectPascal
Raw Permalink Normal View History

{********************************************************************}
{ }
{ Developer Express Visual Component Library }
{ ExpressLayoutControl main components }
{ }
{ Copyright (c) 2001-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 EXPRESSLAYOUTCONTROL 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 dxLayoutControl;
{$I cxVer.inc}
interface
uses
Messages, Windows, SysUtils, Classes, Controls, Graphics, Forms, StdCtrls, ExtCtrls, IniFiles, Contnrs,
dxCore, cxClasses, cxGeometry, cxGraphics, cxControls, cxLookAndFeels, cxLibraryConsts,
dxLayoutLookAndFeels, dxLayoutCommon, cxPC, dxControlSelection;
const
htError = -1;
htNone = 0;
htCustomizeForm = 1;
htItem = 10;
htGroup = 20;
htClientArea = 30;
htAvailableItems = 40;
htTreeViewItems = 50;
dxLayoutItemControlDefaultMinHeight = 20;
dxLayoutItemControlDefaultMinWidth = 20;
dxLayoutItemMinSize = 5;
// DXM_FREEITEM = WM_DX + 25;
DXM_PLACECONTROLS = WM_DX + 26;
DXM_BUILDSELECTIONLAYER = WM_DX + 27;
type
//Base
TdxCustomLayoutItem = class;
TdxCustomLayoutItemClass = class of TdxCustomLayoutItem;
TdxLayoutItem = class;
TdxLayoutGroup = class;
TdxLayoutGroupClass = class of TdxLayoutGroup;
TdxCustomLayoutControl = class;
//Secondary
TdxLayoutAlignmentConstraint = class;
TdxCustomLayoutHitTest = class;
TdxLayoutGroupHelper = class;
TdxLayoutGroupHelperClass = class of TdxLayoutGroupHelper;
//Painter
TdxCustomLayoutItemPainterClass = class of TdxCustomLayoutItemPainter;
TdxCustomLayoutItemPainter = class;
TdxLayoutItemPainterClass = class of TdxLayoutItemPainter;
TdxLayoutItemPainter = class;
TdxLayoutGroupPainterClass = class of TdxLayoutGroupPainter;
TdxLayoutGroupPainter = class;
TdxLayoutControlPainterClass = class of TdxLayoutControlPainter;
TdxLayoutControlPainter = class;
TdxLayoutItemControlPainterClass = class of TdxLayoutItemControlPainter;
TdxLayoutItemControlPainter = class;
TdxCustomLayoutItemCaptionPainterClass = class of TdxCustomLayoutItemCaptionPainter;
TdxCustomLayoutItemCaptionPainter = class;
// ViewInfo
TdxCustomLayoutElementViewInfo = class;
TdxCustomLayoutItemElementViewInfo = class;
TdxCustomLayoutItemCaptionViewInfo = class;
TdxCustomLayoutItemViewInfoClass = class of TdxCustomLayoutItemViewInfo;
TdxCustomLayoutItemViewInfo = class;
TdxLayoutItemControlViewInfo = class;
TdxLayoutItemViewInfoClass = class of TdxLayoutItemViewInfo;
TdxLayoutItemViewInfo = class;
TdxLayoutGroupViewInfoClass = class of TdxLayoutGroupViewInfo;
TdxLayoutGroupViewInfo = class;
TdxLayoutControlViewInfoClass = class of TdxLayoutControlViewInfo;
TdxLayoutControlViewInfo = class;
TdxLayoutGroupViewInfoSpecific = class;
TdxLayoutGroupViewInfoSpecificClass = class of TdxLayoutGroupViewInfoSpecific;
// custom item
TdxLayoutAlignHorz = (ahLeft, ahCenter, ahRight, ahClient, ahParentManaged);
TdxLayoutAlignVert = (avTop, avCenter, avBottom, avClient, avParentManaged);
TdxLayoutAutoAlign = (aaHorizontal, aaVertical);
TdxLayoutAutoAligns = set of TdxLayoutAutoAlign;
TdxLayoutDirection = (ldHorizontal, ldVertical, ldTabbed);
TdxLayoutAreaPart = (apNone, apLeft, apTop, apRight, apBottom, apCenter,
apBeforeContent, apAfterContent);
TdxCustomLayoutItemOptions = class(TPersistent)
private
FItem: TdxCustomLayoutItem;
protected
procedure Changed; virtual;
property Item: TdxCustomLayoutItem read FItem;
public
constructor Create(AItem: TdxCustomLayoutItem); virtual;
end;
TdxCustomLayoutItemCaptionOptions = class(TdxCustomLayoutItemOptions)
private
FAlignHorz: TAlignment;
FShowAccelChar: Boolean;
procedure SetAlignHorz(Value: TAlignment);
procedure SetShowAccelChar(Value: Boolean);
public
constructor Create(AItem: TdxCustomLayoutItem); override;
published
property AlignHorz: TAlignment read FAlignHorz write SetAlignHorz default taLeftJustify;
property ShowAccelChar: Boolean read FShowAccelChar write SetShowAccelChar default True;
end;
TdxCustomLayoutItemCaptionOptionsClass = class of TdxCustomLayoutItemCaptionOptions;
TdxLayoutOffsets = class(TdxCustomLayoutItemOptions)
private
FBottom: Integer;
FLeft: Integer;
FRight: Integer;
FTop: Integer;
function GetValue(Index: Integer): Integer;
procedure SetValue(Index: Integer; Value: Integer);
published
property Bottom: Integer index 1 read GetValue write SetValue default 0;
property Left: Integer index 2 read GetValue write SetValue default 0;
property Right: Integer index 3 read GetValue write SetValue default 0;
property Top: Integer index 4 read GetValue write SetValue default 0;
end;
IdxLayoutSelectableItem = interface
['{2887168D-78EB-44A0-A440-E284B01BE407}']
function CanDelete: Boolean;
function IsChild(AOwner: TdxCustomLayoutControl): Boolean;
procedure SelectComponent(AShift: TShiftState = []);
procedure SelectParent;
procedure SelectionChanged;
function IsVisible: Boolean;
end;
TdxLayoutItemChangeType = (ictHard, ictMedium, ictLight);
TdxCustomLayoutItem = class(TComponent, IdxLayoutLookAndFeelUser, IdxLayoutSelectableItem)
private
FAlignHorz: TdxLayoutAlignHorz;
FAlignmentConstraint: TdxLayoutAlignmentConstraint;
FAlignVert: TdxLayoutAlignVert;
FAllowRemove: Boolean;
FCachedTextHeight: Integer;
FCaption: string;
FCaptionOptions: TdxCustomLayoutItemCaptionOptions;
FContainer: TdxCustomLayoutControl;
FEnabled: Boolean;
FLayoutLookAndFeel: TdxCustomLayoutLookAndFeel;
FOffsets: TdxLayoutOffsets;
FParent: TdxLayoutGroup;
FShowCaption: Boolean;
FViewInfo: TdxCustomLayoutItemViewInfo;
FVisible: Boolean;
FOnCaptionClick: TNotifyEvent;
function GetRealAlignHorz: TdxLayoutAlignHorz;
function GetRealAlignVert: TdxLayoutAlignVert;
function GetActuallyVisible: Boolean;
function GetAutoAligns: TdxLayoutAutoAligns;
function GetAlignHorz: TdxLayoutAlignHorz;
function GetAlignVert: TdxLayoutAlignVert;
function GetCaptionForCustomizeForm: string;
function GetHasMouse: Boolean;
function GetIndex: Integer;
function GetIsAvailable: Boolean;
function GetIsDesigning: Boolean;
function GetIsDestroying: Boolean;
function GetIsDragged: Boolean;
function GetIsLoading: Boolean;
function GetIsSelected: Boolean;
function GetIsRoot: Boolean;
function GetVisibleIndex: Integer;
procedure SetAlignHorz(Value: TdxLayoutAlignHorz);
procedure SetAlignmentConstraint(Value: TdxLayoutAlignmentConstraint);
procedure SetAlignVert(Value: TdxLayoutAlignVert);
procedure SetAutoAligns(Value: TdxLayoutAutoAligns);
procedure SetCaption(const Value: string);
procedure SetContainer(Value: TdxCustomLayoutControl);
procedure SetEnabled(Value: Boolean);
procedure SetLayoutLookAndFeel(Value: TdxCustomLayoutLookAndFeel);
procedure SetHasMouse(Value: Boolean);
procedure SetIndex(Value: Integer);
procedure SetParent(Value: TdxLayoutGroup);
procedure SetShowCaption(Value: Boolean);
procedure SetVisible(Value: Boolean);
procedure SetVisibleIndex(Value: Integer);
function IsAlignHorzStored: Boolean;
function IsAlignVertStored: Boolean;
protected
procedure SetName(const Value: TComponentName); override;
procedure SetParentComponent(Value: TComponent); override;
procedure LayoutLookAndFeelChanged; virtual;
procedure LayoutLookAndFeelChanging; virtual;
// IdxLayoutLookAndFeelUser
procedure IdxLayoutLookAndFeelUser.BeginLookAndFeelDestroying = BeginLayoutLookAndFeelUserDestroying;
procedure IdxLayoutLookAndFeelUser.EndLookAndFeelDestroying = EndLayoutLookAndFeelUserDestroying;
procedure IdxLayoutLookAndFeelUser.LookAndFeelChanged = LayoutLookAndFeelUserChanged;
procedure IdxLayoutLookAndFeelUser.LookAndFeelDestroyed = LayoutLookAndFeelUserDestroyed;
procedure BeginLayoutLookAndFeelUserDestroying; stdcall;
procedure EndLayoutLookAndFeelUserDestroying; stdcall;
procedure LayoutLookAndFeelUserChanged; stdcall;
procedure LayoutLookAndFeelUserDestroyed; stdcall;
function CanFocusOnClick(X, Y: Integer): Boolean; virtual;
function CanProcessAccel(out AItem: TdxCustomLayoutItem): Boolean; virtual; abstract;
function CanRemove: Boolean; virtual;
procedure ContainerChanged; virtual;
procedure DoCaptionDown; dynamic;
procedure DoCaptionClick; dynamic;
procedure DoPack; virtual;
function DoProcessAccel: Boolean; dynamic;
procedure EnabledChanged; virtual;
function GetParentManagedAlignHorz: TdxLayoutAlignHorz; virtual;
function GetParentManagedAlignVert: TdxLayoutAlignVert; virtual;
function GetBaseName: string; virtual;
function GetCursor(X, Y: Integer): TCursor; virtual;
function GetEnabledForWork: Boolean; virtual;
function GetLayoutLookAndFeel: TdxCustomLayoutLookAndFeel; virtual;
function GetParentHelperClass: TdxLayoutGroupHelperClass;
function GetShowCaption: Boolean; virtual; // #DG !!!
function GetViewInfoClass: TdxCustomLayoutItemViewInfoClass; virtual; abstract;
function GetVisible: Boolean;
function HasControl: Boolean; virtual;
procedure BeforeCalculateViewInfo; virtual;
procedure AfterCalculateViewInfo; virtual;
function IsParentGroup(AParentGroup: TdxLayoutGroup): Boolean;
function IsChildItem(AChildItem: TdxCustomLayoutItem): Boolean;
function HasCaption: Boolean; virtual; // #DG !!!
procedure Init; virtual;
procedure MouseEnter; dynamic;
procedure MouseLeave; dynamic;
procedure CustomizationMouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); virtual;
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); dynamic;
procedure MouseMove(Shift: TShiftState; X, Y: Integer); dynamic;
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); dynamic;
procedure ProcessAccel; dynamic;
function ProcessDialogChar(ACharCode: Word): Boolean; virtual;
procedure RestoreItemControlSize; virtual; abstract;
function GetCaptionOptionsClass: TdxCustomLayoutItemCaptionOptionsClass; virtual;
procedure ResetCachedTextHeight;
//IdxLayoutSelectableItem
function CanDelete: Boolean; virtual;
function IsChild(AOwner: TdxCustomLayoutControl): Boolean; virtual;
procedure SelectComponent(AShift: TShiftState = []); virtual;
procedure SelectParent; virtual;
procedure SelectionChanged; virtual;
function IdxLayoutSelectableItem.IsVisible = IsSelectableItemVisible;
function IsSelectableItemVisible: Boolean; virtual;
property CachedTextHeight: Integer read FCachedTextHeight write FCachedTextHeight;
property EnabledForWork: Boolean read GetEnabledForWork;
property HasMouse: Boolean read GetHasMouse write SetHasMouse;
property IsAvailable: Boolean read GetIsAvailable;
property IsDesigning: Boolean read GetIsDesigning;
property IsDestroying: Boolean read GetIsDestroying;
property IsDragged: Boolean read GetIsDragged;
property IsLoading: Boolean read GetIsLoading;
property IsSelected: Boolean read GetIsSelected;
public
constructor Create(AOwner: TComponent); override;
procedure BeforeDestruction; override;
destructor Destroy; override;
function GetParentComponent: TComponent; override;
function HasParent: Boolean; override;
procedure Changed(AType: TdxLayoutItemChangeType = ictHard);
function CanMoveTo(AParent: TdxCustomLayoutItem): Boolean; virtual;
procedure MakeVisible;
function Move(AParent: TdxLayoutGroup; AIndex: Integer; APack: Boolean = False): Boolean;
function MoveTo(AParent: TdxLayoutGroup; AVisibleIndex: Integer; APack: Boolean = False): Boolean;
procedure Pack;
function PutIntoHiddenGroup(ALayoutDirection: TdxLayoutDirection): TdxLayoutGroup;
property ActuallyVisible: Boolean read GetActuallyVisible;
property CaptionForCustomizeForm: string read GetCaptionForCustomizeForm;
property Container: TdxCustomLayoutControl read FContainer write SetContainer;
property Index: Integer read GetIndex write SetIndex;
property IsRoot: Boolean read GetIsRoot;
property Parent: TdxLayoutGroup read FParent write SetParent;
property ViewInfo: TdxCustomLayoutItemViewInfo read FViewInfo;
property VisibleIndex: Integer read GetVisibleIndex write SetVisibleIndex;
published
property AutoAligns: TdxLayoutAutoAligns read GetAutoAligns write SetAutoAligns stored False; // obsolette
property AlignHorz: TdxLayoutAlignHorz read GetAlignHorz write SetAlignHorz stored IsAlignHorzStored;
property AlignVert: TdxLayoutAlignVert read GetAlignVert write SetAlignVert stored IsAlignVertStored;
property AlignmentConstraint: TdxLayoutAlignmentConstraint read FAlignmentConstraint
write SetAlignmentConstraint;
property AllowRemove: Boolean read FAllowRemove write FAllowRemove default True;
property Caption: string read FCaption write SetCaption;
property CaptionOptions: TdxCustomLayoutItemCaptionOptions read FCaptionOptions write FCaptionOptions;
property Enabled: Boolean read FEnabled write SetEnabled default True;
property LookAndFeel: TdxCustomLayoutLookAndFeel read FLayoutLookAndFeel write SetLayoutLookAndFeel stored False; // osolette
property LayoutLookAndFeel: TdxCustomLayoutLookAndFeel read FLayoutLookAndFeel write SetLayoutLookAndFeel;
property Offsets: TdxLayoutOffsets read FOffsets write FOffsets;
property ShowCaption: Boolean read GetShowCaption write SetShowCaption default True;
property Visible: Boolean read FVisible write SetVisible default True;
property OnCaptionClick: TNotifyEvent read FOnCaptionClick write FOnCaptionClick;
end;
// item
TdxCustomLayoutControlAdapter = class(TPersistent)
private
FItem: TdxLayoutItem;
function GetControl: TControl;
function GetLayoutLookAndFeel: TdxCustomLayoutLookAndFeel;
protected
function AllowCheckSize: Boolean; virtual;
procedure HideControlBorder; virtual;
procedure Init; virtual;
function ShowBorder: Boolean; virtual;
function ShowItemCaption: Boolean; virtual;
function UseItemColor: Boolean; virtual;
property Control: TControl read GetControl;
property Item: TdxLayoutItem read FItem;
property LayoutLookAndFeel: TdxCustomLayoutLookAndFeel read GetLayoutLookAndFeel;
public
constructor Create(AItem: TdxLayoutItem); virtual;
procedure LayoutLookAndFeelChanged; virtual;
class procedure Register(AControlClass: TControlClass);
class procedure Unregister(AControlClass: TControlClass);
end;
TdxCustomLayoutControlAdapterClass = class of TdxCustomLayoutControlAdapter;
TdxCaptionLayout = (clLeft, clTop, clRight, clBottom);
TdxAlignmentVert = (tavTop, tavCenter, tavBottom);
TdxLayoutItemCaptionOptions = class(TdxCustomLayoutItemCaptionOptions)
private
FAlignVert: TdxAlignmentVert;
FLayout: TdxCaptionLayout;
FWidth: Integer;
procedure SetAlignVert(Value: TdxAlignmentVert);
procedure SetLayout(Value: TdxCaptionLayout);
procedure SetWidth(Value: Integer);
published
constructor Create(AItem: TdxCustomLayoutItem); override;
property AlignVert: TdxAlignmentVert read FAlignVert write SetAlignVert default tavCenter;
property Layout: TdxCaptionLayout read FLayout write SetLayout default clLeft;
property Width: Integer read FWidth write SetWidth default 0;
end;
TdxLayoutItemControlOptions = class(TdxCustomLayoutItemOptions)
private
FAutoAlignment: Boolean;
FAutoColor: Boolean;
FFixedSize: Boolean;
FMinHeight: Integer;
FMinWidth: Integer;
FOpaque: Boolean;
FShowBorder: Boolean;
procedure SetAutoAlignment(Value: Boolean);
procedure SetAutoColor(Value: Boolean);
procedure SetFixedSize(Value: Boolean);
procedure SetMinHeight(Value: Integer);
procedure SetMinWidth(Value: Integer);
procedure SetOpaque(Value: Boolean);
procedure SetShowBorder(Value: Boolean);
public
constructor Create(AItem: TdxCustomLayoutItem); override;
published
property AutoAlignment: Boolean read FAutoAlignment write SetAutoAlignment default True;
property AutoColor: Boolean read FAutoColor write SetAutoColor default False;
property FixedSize: Boolean read FFixedSize write SetFixedSize default False;
property MinHeight: Integer read FMinHeight write SetMinHeight default dxLayoutItemControlDefaultMinHeight;
property MinWidth: Integer read FMinWidth write SetMinWidth default dxLayoutItemControlDefaultMinWidth;
property Opaque: Boolean read FOpaque write SetOpaque default False;
property ShowBorder: Boolean read FShowBorder write SetShowBorder default True;
end;
TdxLayoutItemControlOptionsClass = class of TdxLayoutItemControlOptions;
TdxLayoutItem = class(TdxCustomLayoutItem)
private
FControl: TControl;
FControlLocked: Boolean;
FControlAdapter: TdxCustomLayoutControlAdapter;
FControlOptions: TdxLayoutItemControlOptions;
FControlSizeBeforeDestruction: TPoint;
FOriginalControlSize: TPoint;
FDesignSelectorControls: TcxComponentList;
FDefaultControlWndProc: TWndMethod;
function GetCaptionOptions: TdxLayoutItemCaptionOptions;
function GetViewInfo: TdxLayoutItemViewInfo;
procedure SetCaptionOptions(Value: TdxLayoutItemCaptionOptions);
procedure SetControl(Value: TControl);
function CanFocusControlOnCaptionClick: Boolean;
procedure CreateControlAdapter;
//procedure PostFree;
protected
function CanDelete: Boolean; override;
function CanFocusOnClick(X, Y: Integer): Boolean; override;
function CanProcessAccel(out AItem: TdxCustomLayoutItem): Boolean; override;
procedure ContainerChanged; override;
procedure DoCaptionDown; override;
procedure EnabledChanged; override;
function GetParentManagedAlignVert: TdxLayoutAlignVert; override;
function GetBaseName: string; override;
function GetViewInfoClass: TdxCustomLayoutItemViewInfoClass; override;
procedure Init; override;
procedure Loaded; override;
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
procedure ProcessAccel; override;
procedure RestoreItemControlSize; override;
procedure CustomizationMouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
procedure AfterCalculateViewInfo; override;
procedure LayoutLookAndFeelChanged; override;
function GetCaptionOptionsClass: TdxCustomLayoutItemCaptionOptionsClass; override;
function GetControlOptionsClass: TdxLayoutItemControlOptionsClass; virtual;
function CanFocusControl: Boolean; virtual;
function CanTabStopControl: Boolean;
procedure ControlWndProc(var Message: TMessage); virtual;
function HasControl: Boolean; override;
function HasWinControl: Boolean;
procedure SaveControlSizeBeforeDestruction;
procedure SaveOriginalControlSize;
procedure SetControlEnablement;
procedure SetControlFocus;
procedure SetControlVisibility;
procedure UpdateDesignSelectors;
property ControlAdapter: TdxCustomLayoutControlAdapter read FControlAdapter;
property ControlSizeBeforeDestruction: TPoint read FControlSizeBeforeDestruction;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
property OriginalControlSize: TPoint read FOriginalControlSize write FOriginalControlSize;
property ViewInfo: TdxLayoutItemViewInfo read GetViewInfo;
published
property CaptionOptions: TdxLayoutItemCaptionOptions read GetCaptionOptions
write SetCaptionOptions;
property Control: TControl read FControl write SetControl;
property ControlOptions: TdxLayoutItemControlOptions read FControlOptions
write FControlOptions;
end;
TdxLayoutItemClass = class of TdxLayoutItem;
// group
TdxLayoutGroupHelper = class
public
class function GetChildItemsAlignHorz: TdxLayoutAlignHorz; virtual;
class function GetChildItemsAlignVert: TdxLayoutAlignVert; virtual;
class function GetOrthogonalDirection: TdxLayoutDirection; virtual; abstract;
class function GetSpecificClass: TdxLayoutGroupViewInfoSpecificClass; virtual; abstract;
end;
TdxLayoutHorizontalGroupHelper = class(TdxLayoutGroupHelper)
public
class function GetChildItemsAlignHorz: TdxLayoutAlignHorz; override;
class function GetChildItemsAlignVert: TdxLayoutAlignVert; override;
class function GetOrthogonalDirection: TdxLayoutDirection; override;
class function GetSpecificClass: TdxLayoutGroupViewInfoSpecificClass; override;
end;
TdxLayoutVerticalGroupHelper = class(TdxLayoutGroupHelper)
public
class function GetChildItemsAlignHorz: TdxLayoutAlignHorz; override;
class function GetChildItemsAlignVert: TdxLayoutAlignVert; override;
class function GetOrthogonalDirection: TdxLayoutDirection; override;
class function GetSpecificClass: TdxLayoutGroupViewInfoSpecificClass; override;
end;
TdxLayoutTabbedGroupHelper = class(TdxLayoutHorizontalGroupHelper)
public
class function GetChildItemsAlignHorz: TdxLayoutAlignHorz; override;
class function GetChildItemsAlignVert: TdxLayoutAlignVert; override;
class function GetOrthogonalDirection: TdxLayoutDirection; override;
class function GetSpecificClass: TdxLayoutGroupViewInfoSpecificClass; override;
end;
TdxLayoutGroup = class(TdxCustomLayoutItem)
private
FItemIndex: Integer;
FHidden: Boolean;
FIsUserDefined: Boolean;
FItems: TcxComponentList;
FVisibleItems: TcxComponentList;
FLayoutDirection: TdxLayoutDirection;
FLocked: Boolean;
FLayoutLookAndFeelException: Boolean;
FShowBorder: Boolean;
FUseIndent: Boolean;
function GetCount: Integer;
function GetItem(Index: Integer): TdxCustomLayoutItem;
function GetShowBorder: Boolean;
function GetViewInfo: TdxLayoutGroupViewInfo;
function GetVisibleCount: Integer;
function GetVisibleItem(Index: Integer): TdxCustomLayoutItem;
procedure SetItemIndex(Value: Integer);
procedure SetHidden(Value: Boolean);
procedure SetLayoutDirection(Value: TdxLayoutDirection);
procedure SetLocked(Value: Boolean);
procedure SetLayoutLookAndFeelException(Value: Boolean);
procedure SetShowBorder(Value: Boolean);
procedure SetUseIndent(Value: Boolean);
procedure AddItem(AItem: TdxCustomLayoutItem);
procedure ExtractItem(AItem: TdxCustomLayoutItem);
procedure ItemListChanged(Sender: TObject; AComponent: TComponent; AAction: TcxComponentCollectionNotification);
function IsChildActuallyVisible(AChild: TdxCustomLayoutItem): Boolean;
function GetChildLayoutLookAndFeel: TdxCustomLayoutLookAndFeel;
protected
procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override;
procedure Loaded; override;
procedure SetChildOrder(Child: TComponent; Order: Integer); override;
procedure SetParentComponent(Value: TComponent); override;
// TdxCustomLayoutItem
function CanDelete: Boolean; override;
function CanProcessAccel(out AItem: TdxCustomLayoutItem): Boolean; override;
function CanRemove: Boolean; override;
procedure ContainerChanged; override;
procedure DoPack; override;
procedure EnabledChanged; override;
function GetBaseName: string; override;
function GetShowCaption: Boolean; override;
function GetViewInfoClass: TdxCustomLayoutItemViewInfoClass; override;
function ProcessDialogChar(ACharCode: Word): Boolean; override;
procedure RestoreItemControlSize; override;
procedure LayoutLookAndFeelChanged; override;
procedure LayoutLookAndFeelChanging; override;
procedure BeforeCalculateViewInfo; override;
procedure AfterCalculateViewInfo; override;
function CanDestroy: Boolean; virtual;
procedure BuildVisibleItemsList;
function GetHelperClass: TdxLayoutGroupHelperClass;
function AllowDrawChild(AChild: TdxCustomLayoutItem): Boolean; virtual;
procedure ChangeItemIndex(AItem: TdxCustomLayoutItem; Value: Integer);
procedure ChangeItemVisibleIndex(AItem: TdxCustomLayoutItem; Value: Integer);
function GetItemIndex(AItemVisibleIndex: Integer): Integer;
function IndexOf(AItem: TdxCustomLayoutItem): Integer;
function VisibleIndexOf(AItem: TdxCustomLayoutItem): Integer;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
function CreateGroup(AGroupClass: TdxLayoutGroupClass = nil): TdxLayoutGroup;
function CreateItem(AItemClass: TdxCustomLayoutItemClass = nil): TdxCustomLayoutItem;
function CreateItemForControl(AControl: TControl): TdxLayoutItem;
function CanMoveTo(AParent: TdxCustomLayoutItem): Boolean; override;
procedure MoveChildrenToParent;
function PutChildrenIntoHiddenGroup: TdxLayoutGroup;
property Count: Integer read GetCount;
property Items[Index: Integer]: TdxCustomLayoutItem read GetItem; default;
property IsUserDefined: Boolean read FIsUserDefined;
property ViewInfo: TdxLayoutGroupViewInfo read GetViewInfo;
property VisibleCount: Integer read GetVisibleCount;
property VisibleItems[Index: Integer]: TdxCustomLayoutItem read GetVisibleItem;
published
property ItemIndex: Integer read FItemIndex write SetItemIndex default 0;
property Hidden: Boolean read FHidden write SetHidden default False;
property LayoutDirection: TdxLayoutDirection read FLayoutDirection write SetLayoutDirection default ldVertical;
property Locked: Boolean read FLocked write SetLocked default False;
property LookAndFeelException: Boolean read FLayoutLookAndFeelException write SetLayoutLookAndFeelException stored False; // obsolette
property LayoutLookAndFeelException: Boolean read FLayoutLookAndFeelException write SetLayoutLookAndFeelException default False;
property ShowBorder: Boolean read GetShowBorder write SetShowBorder default True;
property UseIndent: Boolean read FUseIndent write SetUseIndent default True;
end;
// alignment constraint
TdxLayoutAlignmentConstraintKind = (ackLeft, ackTop, ackRight, ackBottom);
TdxLayoutAlignmentConstraint = class(TComponent)
private
FControl: TdxCustomLayoutControl;
FItems: TList;
FKind: TdxLayoutAlignmentConstraintKind;
function GetCount: Integer;
function GetItem(Index: Integer): TdxCustomLayoutItem;
procedure SetKind(Value: TdxLayoutAlignmentConstraintKind);
procedure CreateItems;
procedure DestroyItems;
procedure InternalAddItem(AItem: TdxCustomLayoutItem);
procedure InternalRemoveItem(AItem: TdxCustomLayoutItem);
protected
procedure SetParentComponent(Value: TComponent); override;
procedure BeginUpdate;
function CanAddItem(AItem: TdxCustomLayoutItem): Boolean; virtual;
procedure Changed; virtual;
procedure EndUpdate;
property Control: TdxCustomLayoutControl read FControl;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
function GetParentComponent: TComponent; override;
function HasParent: Boolean; override;
procedure AddItem(AItem: TdxCustomLayoutItem);
procedure RemoveItem(AItem: TdxCustomLayoutItem);
property Count: Integer read GetCount;
property Items[Index: Integer]: TdxCustomLayoutItem read GetItem;
published
property Kind: TdxLayoutAlignmentConstraintKind read FKind write SetKind default ackLeft;
end;
TdxLayoutAlignmentConstraintClass = class of TdxLayoutAlignmentConstraint;
{ DragAndDrop }
TdxLayoutDragSource = (dsControl, dsCustomizeFormAvailableItems, dsCustomizeFormTreeViewItems);
{ TdxLayoutControlDragAndDropObject }
TdxLayoutControlDragAndDropObject = class(TcxDragAndDropObject)
private
FAreaPart: TdxLayoutAreaPart;
FDragImage: TcxDragImage;
FDragImageOffset: TPoint;
FDestinationControl: TdxCustomLayoutControl;
FDestinationGroup: TdxLayoutGroup;
FDestinationImage: TcxDragDestinationImage;
FDestinationItem: TdxCustomLayoutItem;
FNeedRepaintDestinationImage: Boolean;
FSource: TdxLayoutDragSource;
FSourceItem: TdxCustomLayoutItem;
FSourceItemBounds: TRect;
FStartDragPoint: TPoint;
function CanDrop: Boolean;
function CanRemove: Boolean;
function GetSourceControl: TdxCustomLayoutControl;
procedure ResetDragAndDrop;
procedure SetAreaPart(Value: TdxLayoutAreaPart);
procedure SetDestinationControl(Value: TdxCustomLayoutControl);
procedure SetDestinationGroup(Value: TdxLayoutGroup);
procedure SetDestinationItem(Value: TdxCustomLayoutItem);
procedure SetSourceItem(Value: TdxCustomLayoutItem);
protected
procedure CreateDragImage;
procedure CreateDestinationImage;
procedure DirtyChanged; override;
function GetDragAndDropCursor(Accepted: Boolean): TCursor; override;
procedure PaintDestinationImage;
procedure PaintDragImage;
procedure RefreshDestinationImage;
procedure ShowDragImage(const P: TPoint);
property AreaPart: TdxLayoutAreaPart read FAreaPart write SetAreaPart;
property DestinationControl: TdxCustomLayoutControl read FDestinationControl write SetDestinationControl;
property DestinationGroup: TdxLayoutGroup read FDestinationGroup write SetDestinationGroup;
property DestinationItem: TdxCustomLayoutItem read FDestinationItem write SetDestinationItem;
property Source: TdxLayoutDragSource read FSource write FSource;
property SourceControl: TdxCustomLayoutControl read GetSourceControl;
property SourceItemBounds: TRect read FSourceItemBounds;
public
destructor Destroy; override;
procedure BeginDragAndDrop; override;
procedure DragAndDrop(const P: TPoint; var Accepted: Boolean); override;
procedure EndDragAndDrop(Accepted: Boolean); override;
procedure Init(ASource: TdxLayoutDragSource; ASourceItem: TdxCustomLayoutItem); virtual;
property SourceItem: TdxCustomLayoutItem read FSourceItem write SetSourceItem;
end;
{ TdxLayoutControlPersistent }
TdxLayoutControlPersistent = class(TPersistent)
private
FControl: TdxCustomLayoutControl;
protected
procedure Changed; virtual;
function GetOwner: TPersistent; override;
public
constructor Create(AControl: TdxCustomLayoutControl); virtual;
property Control: TdxCustomLayoutControl read FControl;
end;
{ TdxLayoutDragAndDropHelper }
TdxLayoutDragAndDropHelper = class(TdxLayoutControlPersistent)
private
FDragItem: TdxCustomLayoutItem;
FMouseDownPos: TPoint;
procedure BeginDragAndDrop(ASource: TdxLayoutDragSource);
function CanBeginDragAndDrop(X, Y: Integer): Boolean;
function GetDragAndDropObject: TdxLayoutControlDragAndDropObject;
protected
property DragAndDropObject: TdxLayoutControlDragAndDropObject read GetDragAndDropObject;
public
constructor Create(AControl: TdxCustomLayoutControl); override;
procedure InitializeDragItem(AItem: TdxCustomLayoutItem; X, Y: Integer);
procedure Reset;
procedure TryBeginDragAndDrop(X, Y: Integer; ASource: TdxLayoutDragSource);
property DragItem: TdxCustomLayoutItem read FDragItem;
end;
{ controls }
TdxStoringOptions = class(TPersistent)
private
FIniFileName: string;
FRegistryPath: string;
FStoreToIniFile: Boolean;
FStoreToRegistry: Boolean;
protected
function CanStoreToIniFile: Boolean;
function CanStoreToRegistry: Boolean;
function CanRestoreFromIniFile: Boolean;
function CanRestoreFromRegistry: Boolean;
public
procedure Assign(Source: TPersistent); override;
published
property IniFileName: string read FIniFileName write FIniFileName;
property RegistryPath: string read FRegistryPath write FRegistryPath;
property StoreToIniFile: Boolean read FStoreToIniFile write FStoreToIniFile default False;
property StoreToRegistry: Boolean read FStoreToRegistry write FStoreToRegistry default False;
end;
TdxLayoutAutoContentSize = (acsWidth, acsHeight);
TdxLayoutAvailableItemsViewKind = (oivkList, oivkTree);
TdxLayoutCustomizeFormUpdateType = (cfutCaption, cfutContent, cfutSelection);
TdxLayoutCustomizeFormUpdateTypes = set of TdxLayoutCustomizeFormUpdateType;
TdxLayoutAutoContentSizes = set of TdxLayoutAutoContentSize;
TdxCustomLayoutControl = class(TcxControl, IdxLayoutLookAndFeelUser, IdxLayoutComponent,
IdxSkinSupport, IdxLayoutDesignerHelper, IdxLayoutSelectionChanged)
private
FAlignmentConstraints: TList;
FAutoControlAlignment: Boolean;
FAutoControlTabOrders: Boolean;
FBoldFont: TFont;
FFocusControlOnItemCaptionClick: Boolean;
FItemWithMouse: TdxCustomLayoutItem;
FLeftPos: Integer;
FOptionsStoring: TdxStoringOptions;
FRightButtonPressed: Boolean;
FShowHiddenGroupsBounds: Boolean;
FTopPos: Integer;
FUpdateLockCount: Integer;
// Objects
FRootGroup: TdxLayoutGroup;
FLayoutLookAndFeel: TdxCustomLayoutLookAndFeel;
FPainter: TdxLayoutControlPainter;
FViewInfo: TdxLayoutControlViewInfo;
// Items
FAbsoluteItems: TcxComponentList;
FAvailableItems: TcxComponentList;
// Customization
FShowDesignSelectors: Boolean;
FHighlightRoot: Boolean;
FCustomization: Boolean;
FCustomizationControls: TcxComponentList;
FCustomizeAvailableItemsViewKind: TdxLayoutAvailableItemsViewKind;
FCustomizeForm: TCustomForm;
FCustomizeFormBounds: TRect;
FCustomizeFormClass: TFormClass;
FCustomizeFormTabbedView: Boolean;
FCustomizeFormUpdateLockCount: Integer;
// Internal Flags
FIsPlaceControlsNeeded: Boolean;
FIsPlacingControls: Boolean;
// Storing
FStoredStream: TMemoryStream;
FOnCustomization: TNotifyEvent;
// Get/Set Properties
function GetAbsoluteItem(Index: Integer): TdxCustomLayoutItem;
function GetAbsoluteItemCount: Integer;
function GetAlignmentConstraint(Index: Integer): TdxLayoutAlignmentConstraint;
function GetAlignmentConstraintCount: Integer;
function GetAllowDrop: Boolean;
function GetAvailableItem(Index: Integer): TdxCustomLayoutItem;
function GetAvailableItemCount: Integer;
function GetAutoContentSizes: TdxLayoutAutoContentSizes;
function GetContentBounds: TRect;
function GetLayoutDirection: TdxLayoutDirection;
function GetOccupiedClientWidth: Integer;
function GetOccupiedClientHeight: Integer;
function GetSelectedControlCount: Integer;
procedure SetAutoContentSizes(Value: TdxLayoutAutoContentSizes);
procedure SetAutoControlAlignment(Value: Boolean);
procedure SetAutoControlTabOrders(Value: Boolean);
procedure SetCustomization(Value: Boolean);
procedure SetCustomizeAvailableItemsViewKind(Value: TdxLayoutAvailableItemsViewKind);
procedure SetCustomizeFormTabbedView(Value: Boolean);
procedure SetShowDesignSelectors(Value: Boolean);
procedure SetHighlightRoot(Value: Boolean);
procedure SetIsPlaceControlsNeeded(Value: Boolean);
procedure SetRootGroup(Value: TdxLayoutGroup);
procedure SetItemWithMouse(Value: TdxCustomLayoutItem);
procedure SetLeftPos(Value: Integer);
procedure SetLayoutDirection(Value: TdxLayoutDirection);
procedure SetLayoutLookAndFeel(Value: TdxCustomLayoutLookAndFeel);
procedure SetShowHiddenGroupsBounds(Value: Boolean);
procedure SetTopPos(Value: Integer);
// Storing
procedure SetOptionsStoring(Value: TdxStoringOptions);
function GetIniFileName: string;
function GetRegistryPath: string;
function GetStoreInIniFile: Boolean;
function GetStoreInRegistry: Boolean;
procedure SetIniFileName(const Value: string);
procedure SetRegistryPath(const Value: string);
procedure SetStoreInIniFile(const Value: Boolean);
procedure SetStoreInRegistry(const Value: Boolean);
procedure CreateHandlers;
procedure DestroyHandlers;
// Constraints
procedure CreateConstraints;
procedure DestroyConstraints;
procedure AddAlignmentConstraint(AConstraint: TdxLayoutAlignmentConstraint);
procedure RemoveAlignmentConstraint(AConstraint: TdxLayoutAlignmentConstraint);
// Items
procedure AddAbsoluteItem(AItem: TdxCustomLayoutItem);
procedure ExtractAbsoluteItem(AItem: TdxCustomLayoutItem);
procedure AddAvailableItem(AItem: TdxCustomLayoutItem);
procedure ExtractAvailableItem(AItem: TdxCustomLayoutItem);
procedure AvailableItemListChanged(Sender: TObject; AComponent: TComponent; AAction: TcxComponentCollectionNotification);
// Selection
procedure UpdateCustomizationControls;
// Other
procedure InitializeSubControlsCxLookAndFeel;
procedure PlaceControls(AItemViewInfo: TdxCustomLayoutItemViewInfo);
procedure RefreshBoldFont;
procedure WMNCDestroy(var Message: TWMNCDestroy); message WM_NCDESTROY;
{$IFNDEF DELPHI7}
procedure WMPrintClient(var Message: TWMPrintClient); message WM_PRINTCLIENT;
{$ENDIF}
procedure CMControlChange(var Message: TCMControlChange); message CM_CONTROLCHANGE;
procedure CMDialogChar(var Message: TCMDialogChar); message CM_DIALOGCHAR;
//procedure CMFreeItem(var Message: TMessage); message CM_FREEITEM;
procedure DXMPlaceControls(var Message: TMessage); message DXM_PLACECONTROLS;
procedure DXMBuildSelectionLayer(var Message: TMessage); message DXM_BUILDSELECTIONLAYER;
protected
FSelectionHelper: IdxLayoutSelectionHelper;
function CanAutoSize(var NewWidth, NewHeight: Integer): Boolean; override;
procedure AlignControls(AControl: TControl; var Rect: TRect); override;
function AllowAutoDragAndDropAtDesignTime(X, Y: Integer;
Shift: TShiftState): Boolean; override;
function AllowDragAndDropWithoutFocus: Boolean; override;
procedure BoundsChanged; override;
function CanDrag(X, Y: Integer): Boolean; override;
function CanFocusOnClick(X, Y: Integer): Boolean; override;
procedure CreateParams(var Params: TCreateParams); override;
procedure DblClick; override;
procedure FontChanged; override;
{$IFNDEF DELPHI12}
procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override;
{$ENDIF}
function GetCursor(X, Y: Integer): TCursor; override;
function HasBackground: Boolean; override;
function IsInternalControl(AControl: TControl): Boolean; override;
procedure Loaded; override;
procedure Paint; override;
procedure SetName(const Value: TComponentName); override;
{$IFDEF DELPHI7}
procedure SetParentBackground(Value: Boolean); override;
{$ENDIF}
procedure WriteState(Writer: TWriter); override;
procedure WndProc(var Message: TMessage); override;
function GetDesignHitTest(X, Y: Integer; Shift: TShiftState): Boolean; override;
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
procedure MouseLeave(AControl: TControl); override;
procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
procedure InitScrollBarsParameters; override;
function NeedsToBringInternalControlsToFront: Boolean; override;
procedure Scroll(AScrollBarKind: TScrollBarKind; AScrollCode: TScrollCode;
var AScrollPos: Integer); override;
function CanDragAndDrop: Boolean;
function GetDragAndDropObjectClass: TcxDragAndDropObjectClass; override;
function StartDragAndDrop(const P: TPoint): Boolean; override;
function GetLayoutLookAndFeel: TdxCustomLayoutLookAndFeel;
function GetCxLookAndFeel: TcxLookAndFeel;
// IdxLayoutLookAndFeelUser
procedure IdxLayoutLookAndFeelUser.BeginLookAndFeelDestroying = BeginLayoutLookAndFeelUserDestroying;
procedure IdxLayoutLookAndFeelUser.EndLookAndFeelDestroying = EndLayoutLookAndFeelUserDestroying;
procedure IdxLayoutLookAndFeelUser.LookAndFeelChanged = LayoutLookAndFeelUserChanged;
procedure IdxLayoutLookAndFeelUser.LookAndFeelDestroyed = LayoutLookAndFeelUserDestroyed;
procedure BeginLayoutLookAndFeelUserDestroying; stdcall;
procedure EndLayoutLookAndFeelUserDestroying; stdcall;
procedure LayoutLookAndFeelUserChanged; stdcall;
procedure LayoutLookAndFeelUserDestroyed; stdcall;
// IdxLayoutComponent
procedure SelectionChanged; stdcall;
function GetPainterClass: TdxLayoutControlPainterClass; virtual;
function GetViewInfoClass: TdxLayoutControlViewInfoClass; virtual;
procedure AssignItemWithMouse(X, Y: Integer);
function CalculateCustomizeFormBounds(const AFormBounds: TRect): TRect;
function CanMultiSelect: Boolean; virtual;
function CanShowSelection: Boolean; virtual;
procedure CheckLeftPos(var Value: Integer);
procedure CheckPositions;
procedure CheckTopPos(var Value: Integer);
procedure CustomizeFormBeginUpdate;
procedure CustomizeFormCancelUpdate;
procedure CustomizeFormEndUpdate;
procedure CustomizeFormUpdate(AUpdateTypes: TdxLayoutCustomizeFormUpdateTypes);
procedure DoCustomization; dynamic;
procedure DragAndDropBegan; dynamic;
function GetAlignmentConstraintClass: TdxLayoutAlignmentConstraintClass; dynamic;
function GetDefaultGroupClass: TdxLayoutGroupClass; virtual;
function GetDefaultItemClass: TdxLayoutItemClass; virtual;
function GetDesignSelectorRect: TRect;
function IsCustomization: Boolean;
function IsToolSelected: Boolean;
function IsUpdateLocked: Boolean;
procedure LayoutChanged(ANeedPack: Boolean = True);
procedure CreateRootGroup;
procedure PostBuildSelectionLayer; virtual;
//procedure PostFree(AObject: TObject);
procedure ScrollContent(APrevPos, ACurPos: Integer; AHorzScrolling: Boolean);
procedure LoadFromCustomIniFile(AIniFile: TCustomIniFile; const ARootSection: string); virtual;
procedure SaveToCustomIniFile(AIniFile: TCustomIniFile; const ARootSection: string); virtual;
// IdxLayoutDesignerHelper
function CanDeleteComponent(AComponent: TComponent): Boolean;
procedure ClearSelection;
procedure GetSelection(AList: TList);
function IsComponentSelected(AComponent: TPersistent): Boolean;
procedure SelectComponent(AComponent: TPersistent; AShift: TShiftState = []);
procedure SetSelection(AList: TList);
function UniqueName(const BaseName: string): string;
//IdxLayoutSelectionChanged
procedure IdxLayoutSelectionChanged.SelectionChanged = LayoutSelectionChanged;
procedure LayoutSelectionChanged(ASelection: TList; AAction: TdxLayoutSelectionAction);
property AllowDrop: Boolean read GetAllowDrop;
property BoldFont: TFont read FBoldFont;
property IsPlaceControlsNeeded: Boolean read FIsPlaceControlsNeeded write SetIsPlaceControlsNeeded;
property ItemWithMouse: TdxCustomLayoutItem read FItemWithMouse write SetItemWithMouse;
property cxLookAndFeel: TcxLookAndFeel read GetCxLookAndFeel;
property SelectedControlCount: Integer read GetSelectedControlCount;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure BeginDragAndDrop; override;
{$IFDEF DELPHI12}
procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override;
{$ENDIF}
procedure Clear;
function CreateAlignmentConstraint: TdxLayoutAlignmentConstraint;
function FindItem(AControl: TControl): TdxLayoutItem; overload;
function FindItem(const AName: string): TdxCustomLayoutItem; overload;
function GetHitTest(const P: TPoint): TdxCustomLayoutHitTest; overload;
function GetHitTest(X, Y: Integer): TdxCustomLayoutHitTest; overload;
procedure BeginUpdate;
procedure CancelUpdate;
procedure EndUpdate(ANeedPack: Boolean = True);
function CreateGroup(AGroupClass: TdxLayoutGroupClass = nil; AParent: TdxLayoutGroup = nil): TdxLayoutGroup;
function CreateItem(AItemClass: TdxCustomLayoutItemClass = nil; AParent: TdxLayoutGroup = nil): TdxCustomLayoutItem;
function CreateItemForControl(AControl: TControl; AParent: TdxLayoutGroup = nil): TdxLayoutItem;
// Storing
function CanRestore: Boolean;
procedure Restore;
procedure Store;
procedure LoadFromIniFile(const AFileName: string);
procedure LoadFromRegistry(const ARegistryPath: string);
procedure LoadFromStream(AStream: TStream);
procedure SaveToIniFile(const AFileName: string);
procedure SaveToRegistry(const ARegistryPath: string);
procedure SaveToStream(AStream: TStream);
property AbsoluteItemCount: Integer read GetAbsoluteItemCount;
property AbsoluteItems[Index: Integer]: TdxCustomLayoutItem read GetAbsoluteItem;
property AlignmentConstraintCount: Integer read GetAlignmentConstraintCount;
property AlignmentConstraints[Index: Integer]: TdxLayoutAlignmentConstraint read GetAlignmentConstraint;
property AutoContentSizes: TdxLayoutAutoContentSizes read GetAutoContentSizes write SetAutoContentSizes;
property LayoutDirection: TdxLayoutDirection read GetLayoutDirection write SetLayoutDirection;
property AutoControlAlignment: Boolean read FAutoControlAlignment
write SetAutoControlAlignment default True;
property AutoControlTabOrders: Boolean read FAutoControlTabOrders
write SetAutoControlTabOrders default True;
property AvailableItemCount: Integer read GetAvailableItemCount;
property AvailableItems[Index: Integer]: TdxCustomLayoutItem read GetAvailableItem;
property FocusControlOnItemCaptionClick: Boolean read FFocusControlOnItemCaptionClick write FFocusControlOnItemCaptionClick default False;
property Items: TdxLayoutGroup read FRootGroup;
property IsPlacingControls: Boolean read FIsPlacingControls;
property LeftPos: Integer read FLeftPos write SetLeftPos;
property LookAndFeel: TdxCustomLayoutLookAndFeel read FLayoutLookAndFeel write SetLayoutLookAndFeel;
property LayoutLookAndFeel: TdxCustomLayoutLookAndFeel read FLayoutLookAndFeel write SetLayoutLookAndFeel;
property ShowHiddenGroupsBounds: Boolean read FShowHiddenGroupsBounds write SetShowHiddenGroupsBounds;
property TopPos: Integer read FTopPos write SetTopPos;
// Customization properties
property Customization: Boolean read FCustomization write SetCustomization;
property CustomizeAvailableItemsViewKind: TdxLayoutAvailableItemsViewKind read FCustomizeAvailableItemsViewKind
write SetCustomizeAvailableItemsViewKind;
property CustomizeForm: TCustomForm read FCustomizeForm;
property CustomizeFormBounds: TRect read FCustomizeFormBounds write FCustomizeFormBounds;
property CustomizeFormClass: TFormClass read FCustomizeFormClass write FCustomizeFormClass; // must be descendant of TdxLayoutControlCustomizeFormClass
property CustomizeFormTabbedView: Boolean read FCustomizeFormTabbedView write SetCustomizeFormTabbedView;
property ShowDesignSelectors: Boolean read FShowDesignSelectors write SetShowDesignSelectors;
property HighlightRoot: Boolean read FHighlightRoot write SetHighlightRoot;
property ContentBounds: TRect read GetContentBounds;
property OccupiedClientWidth: Integer read GetOccupiedClientWidth;
property OccupiedClientHeight: Integer read GetOccupiedClientHeight;
// Storing properties
property OptionsStoring: TdxStoringOptions read FOptionsStoring write SetOptionsStoring;
property IniFileName: string read GetIniFileName write SetIniFileName;
property RegistryPath: string read GetRegistryPath write SetRegistryPath;
property StoreInIniFile: Boolean read GetStoreInIniFile write SetStoreInIniFile;
property StoreInRegistry: Boolean read GetStoreInRegistry write SetStoreInRegistry;
property Painter: TdxLayoutControlPainter read FPainter;
property ViewInfo: TdxLayoutControlViewInfo read FViewInfo;
property OnCustomization: TNotifyEvent read FOnCustomization write FOnCustomization;
end;
TdxLayoutControl = class(TdxCustomLayoutControl)
published
property Align;
property Anchors;
{$IFDEF DELPHI6}
property BevelEdges;
property BevelInner;
property BevelOuter;
property BevelKind;
property BevelWidth;
property BorderWidth;
{$ENDIF}
property Constraints;
property DragCursor;
property DragKind;
property DragMode;
property Enabled;
property FocusOnClick;
property Font;
{$IFDEF DELPHI7}
property ParentBackground default False;
{$ENDIF}
property ParentFont;
property ParentShowHint;
property PopupMenu;
property ShowHint;
property TabOrder;
property TabStop;
property Visible;
property AutoContentSizes stored False; // obsolette
property AutoControlAlignment;
property AutoControlTabOrders;
property AutoSize;
property FocusControlOnItemCaptionClick;
property LookAndFeel stored False; // obsolette
property LayoutLookAndFeel;
// Customization properties
property CustomizeFormTabbedView default False;
property ShowDesignSelectors default True;
property HighlightRoot default True;
// Storing properties
property OptionsStoring;
property IniFileName stored False; // obsolette
property RegistryPath stored False; // obsolette
property StoreInIniFile stored False; // obsolette
property StoreInRegistry stored False; // obsolette
property OnClick;
property OnContextPopup;
property OnDblClick;
property OnDragDrop;
property OnDragOver;
property OnEndDock;
property OnEndDrag;
property OnEnter;
property OnExit;
property OnKeyDown;
property OnKeyPress;
property OnKeyUp;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
property OnMouseWheel;
property OnMouseWheelDown;
property OnMouseWheelUp;
property OnResize;
property OnStartDock;
property OnStartDrag;
property OnCustomization;
property OnMouseEnter;
property OnMouseLeave;
end;
{ hit tests }
TdxCustomLayoutHitTestClass = class of TdxCustomLayoutHitTest;
TdxCustomLayoutHitTest = class
public
function Cursor: TCursor; dynamic;
class function HitTestCode: Integer; virtual;
class function Instance: TdxCustomLayoutHitTest;
function GetGroupForInsert: TdxLayoutGroup; virtual;
end;
TdxLayoutNoneHitTest = class(TdxCustomLayoutHitTest)
public
class function HitTestCode: Integer; override;
end;
TdxCustomLayoutItemHitTestClass = class of TdxCustomLayoutItemHitTest;
TdxCustomLayoutItemHitTest = class(TdxCustomLayoutHitTest)
private
FItem: TdxCustomLayoutItem;
public
property Item: TdxCustomLayoutItem read FItem write FItem;
end;
TdxLayoutItemHitTest = class(TdxCustomLayoutItemHitTest)
private
function GetItem: TdxLayoutItem;
procedure SetItem(Value: TdxLayoutItem);
public
class function HitTestCode: Integer; override;
function GetGroupForInsert: TdxLayoutGroup; override;
property Item: TdxLayoutItem read GetItem write SetItem;
end;
TdxLayoutGroupHitTest = class(TdxCustomLayoutItemHitTest)
private
function GetItem: TdxLayoutGroup;
procedure SetItem(Value: TdxLayoutGroup);
public
class function HitTestCode: Integer; override;
function GetGroupForInsert: TdxLayoutGroup; override;
property Item: TdxLayoutGroup read GetItem write SetItem;
end;
TdxLayoutCustomizeFormHitTest = class(TdxCustomLayoutHitTest)
public
class function HitTestCode: Integer; override;
end;
TdxLayoutCustomizeFormAvailableItemsHitTest = class(TdxCustomLayoutHitTest)
public
class function HitTestCode: Integer; override;
end;
TdxLayoutCustomizeFormTreeViewItemsHitTest = class(TdxCustomLayoutHitTest)
public
class function HitTestCode: Integer; override;
end;
TdxLayoutClientAreaHitTest = class(TdxCustomLayoutHitTest)
private
FControl: TdxCustomLayoutControl;
public
class function HitTestCode: Integer; override;
property Control: TdxCustomLayoutControl read FControl write FControl;
end;
{ Painters }
{ TdxCustomLayoutElementPainter }
TdxCustomLayoutElementPainter = class
private
FCanvas: TcxCanvas;
FViewInfo: TdxCustomLayoutElementViewInfo;
protected
property Canvas: TcxCanvas read FCanvas;
property ViewInfo: TdxCustomLayoutElementViewInfo read FViewInfo;
public
constructor Create(ACanvas: TcxCanvas; AViewInfo: TdxCustomLayoutElementViewInfo); virtual;
procedure Paint; virtual; abstract;
end;
{ TdxCustomLayoutItemElementPainter }
TdxCustomLayoutItemElementPainter = class(TdxCustomLayoutElementPainter)
private
function GetLayoutLookAndFeel: TdxCustomLayoutLookAndFeel;
function GetViewInfo: TdxCustomLayoutItemElementViewInfo;
protected
property LayoutLookAndFeel: TdxCustomLayoutLookAndFeel read GetLayoutLookAndFeel;
property ViewInfo: TdxCustomLayoutItemElementViewInfo read GetViewInfo;
end;
TdxCustomLayoutItemCaptionPainter = class(TdxCustomLayoutItemElementPainter)
private
function GetViewInfo: TdxCustomLayoutItemCaptionViewInfo;
protected
procedure DoDrawText; virtual;
procedure AfterDrawText; virtual;
procedure BeforeDrawText; virtual;
procedure DrawBackground; virtual;
procedure DrawText;
property ViewInfo: TdxCustomLayoutItemCaptionViewInfo read GetViewInfo;
public
procedure Paint; override;
end;
TdxLayoutGroupCaptionPainter = class(TdxCustomLayoutItemCaptionPainter);
TdxLayoutItemCaptionPainter = class(TdxCustomLayoutItemCaptionPainter);
TdxCustomLayoutItemPainter = class(TdxCustomLayoutElementPainter)
private
function GetLayoutLookAndFeel: TdxCustomLayoutLookAndFeel;
function GetViewInfo: TdxCustomLayoutItemViewInfo;
protected
function GetCaptionPainterClass: TdxCustomLayoutItemCaptionPainterClass; virtual; abstract;
procedure DoDrawBackground; virtual;
procedure DoDrawCaption; virtual;
procedure DoDrawSpecificPart; virtual;
procedure DoDrawSelectionFrame; virtual;
procedure DrawBackground; virtual;
procedure DrawCaption; virtual;
procedure DrawContent; virtual;
procedure DrawItem;
function CanDrawBackground: Boolean; virtual;
function CanDrawCaption: Boolean; virtual;
function CanPaint: Boolean; virtual;
function CanPaintSpecificPart: Boolean; virtual;
property LayoutLookAndFeel: TdxCustomLayoutLookAndFeel read GetLayoutLookAndFeel;
property ViewInfo: TdxCustomLayoutItemViewInfo read GetViewInfo;
public
procedure Paint; override;
// DragImagePaint
procedure PaintSpecificPart; virtual;
procedure PaintDesignFeatures; virtual;
end;
{ TdxLayoutItemControlPainter }
TdxLayoutItemControlPainter = class(TdxCustomLayoutItemElementPainter)
private
function GetViewInfo: TdxLayoutItemControlViewInfo;
protected
procedure DrawBorders; virtual;
property ViewInfo: TdxLayoutItemControlViewInfo read GetViewInfo;
public
procedure Paint; override;
end;
TdxLayoutItemPainter = class(TdxCustomLayoutItemPainter)
private
function GetViewInfo: TdxLayoutItemViewInfo;
protected
function CanDrawBackground: Boolean; override;
function CanDrawCaption: Boolean; override;
function CanPaintSpecificPart: Boolean; override;
function GetCaptionPainterClass: TdxCustomLayoutItemCaptionPainterClass; override;
function GetControlPainterClass: TdxLayoutItemControlPainterClass; virtual;
procedure DoDrawControlBorder; virtual;
procedure DoDrawSpecificPart; override;
procedure DrawContent; override;
procedure DrawControlBorder; virtual;
property ViewInfo: TdxLayoutItemViewInfo read GetViewInfo;
end;
{ TdxLayoutGroupPainter }
TdxLayoutGroupPainter = class(TdxCustomLayoutItemPainter)
private
function GetViewInfo: TdxLayoutGroupViewInfo;
protected
function GetCaptionPainterClass: TdxCustomLayoutItemCaptionPainterClass; override;
procedure DoDrawSpecificPart; override;
procedure DoDrawSelectionFrame; override;
procedure DoDrawBackground; override;
procedure DrawContent; override;
procedure DoDrawBorders; virtual;
procedure DoDrawRestSpace; virtual;
procedure DoDrawBoundsFrame; virtual;
procedure DrawBorders; virtual;
procedure DrawBoundsFrame; virtual;
procedure DrawItems; virtual;
procedure DrawRestSpace; virtual;
procedure DrawItemsArea; virtual;
property ViewInfo: TdxLayoutGroupViewInfo read GetViewInfo;
public
procedure PaintSpecificPart; override;
procedure PaintDesignFeatures; override;
end;
// Layout Control
{ TdxCustomLayoutControlHandler }
TdxCustomLayoutControlHandler = class
private
FControl: TdxCustomLayoutControl;
function GetViewInfo: TdxLayoutControlViewInfo;
protected
property Control: TdxCustomLayoutControl read FControl;
property ViewInfo: TdxLayoutControlViewInfo read GetViewInfo;
public
constructor Create(AControl: TdxCustomLayoutControl); virtual;
end;
TdxLayoutControlPainter = class(TdxCustomLayoutControlHandler)
protected
function GetInternalCanvas: TcxCanvas; virtual;
procedure MakeCanvasClipped(ACanvas: TcxCanvas);
procedure DrawBackground(ACanvas: TcxCanvas); virtual;
procedure DrawDesignSelector(ACanvas: TcxCanvas); virtual;
procedure DrawItems(ACanvas: TcxCanvas); virtual;
procedure DrawDesignFeatures(ACanvas: TcxCanvas);
procedure PlaceControls(AItemViewInfo: TdxCustomLayoutItemViewInfo);
property InternalCanvas: TcxCanvas read GetInternalCanvas;
public
function GetCanvas: TcxCanvas; virtual;
procedure Paint; virtual;
end;
{ ViewInfos }
{ TdxCustomLayoutElementViewInfo }
TdxCustomLayoutElementViewInfo = class
private
FBounds: TRect;
protected
function GetLayoutLookAndFeel: TdxCustomLayoutLookAndFeel; virtual; abstract;
public
procedure Calculate(const ABounds: TRect); virtual;
property Bounds: TRect read FBounds;
property LayoutLookAndFeel: TdxCustomLayoutLookAndFeel read GetLayoutLookAndFeel;
end;
{ TdxCustomLayoutItemElementViewInfo }
TdxCustomLayoutItemElementViewInfo = class(TdxCustomLayoutElementViewInfo)
private
FItemViewInfo: TdxCustomLayoutItemViewInfo;
FHeight: Integer;
FPressed: Boolean;
FWidth: Integer;
function GetItem: TdxCustomLayoutItem;
function GetHeight: Integer;
function GetWidth: Integer;
procedure SetHeight(Value: Integer);
procedure SetWidth(Value: Integer);
protected
function GetLayoutLookAndFeel: TdxCustomLayoutLookAndFeel; override;
function GetEnabled: Boolean; virtual;
function GetEnabledForWork: Boolean; virtual;
function GetCursor(X, Y: Integer): TCursor; virtual;
function GetVisible: Boolean; virtual;
procedure Invalidate(const ABounds: TRect); virtual;
procedure MouseEnter; dynamic;
procedure MouseLeave; dynamic;
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); dynamic;
procedure MouseMove(Shift: TShiftState; X, Y: Integer); dynamic;
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); dynamic;
function WantsMouse(X, Y: Integer): Boolean;
property Item: TdxCustomLayoutItem read GetItem;
property ItemViewInfo: TdxCustomLayoutItemViewInfo read FItemViewInfo;
property Pressed: Boolean read FPressed write FPressed;
property Visible: Boolean read GetVisible;
public
constructor Create(AItemViewInfo: TdxCustomLayoutItemViewInfo); virtual;
function CalculateMinHeight: Integer; virtual;
function CalculateMinWidth: Integer; virtual;
function CalculateHeight: Integer; virtual;
function CalculateWidth: Integer; virtual;
property Enabled: Boolean read GetEnabled;
property EnabledForWork: Boolean read GetEnabledForWork;
property Height: Integer read GetHeight write SetHeight;
property Width: Integer read GetWidth write SetWidth;
end;
TdxCustomLayoutItemCaptionViewInfo = class(TdxCustomLayoutItemElementViewInfo)
private
FHotTracked: Boolean;
function GetCanvas: TcxCanvas;
function GetIsCustomization: Boolean;
function GetTextHeight: Integer;
function GetTextWidth: Integer;
procedure SetHotTracked(Value: Boolean);
protected
function GetCursor(X, Y: Integer): TCursor; override;
function GetVisible: Boolean; override;
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
procedure MouseLeave; override;
procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
function CalculateTextFlags: Integer; virtual;
function CanDoCaptionClick(X, Y: Integer): Boolean; virtual;
function GetAlignHorz: TAlignment; virtual;
function GetAlignVert: TdxAlignmentVert; virtual; abstract;
function GetColor: TColor; virtual;
function GetFont: TFont; virtual;
function GetHotTrackBounds: TRect; virtual;
function GetHotTrackStyles: TdxLayoutHotTrackStyles; virtual;
function GetIsDefaultColor: Boolean; virtual;
function GetIsHotTrackable: Boolean; virtual;
function GetIsTextUnderlined: Boolean; virtual;
function GetIsTransparent: Boolean; virtual;
function GetMultiLine: Boolean; virtual; abstract;
function GetOptions: TdxLayoutLookAndFeelCaptionOptions; virtual;
function GetText: string; virtual;
function GetTextAreaBounds: TRect; virtual;
function GetTextColor: TColor; virtual;
function GetTextHotColor: TColor; virtual;
function GetTextNormalColor: TColor; virtual;
function GetVisibleText: string; virtual;
function IsPointInHotTrackBounds(const P: TPoint): Boolean; virtual;
procedure PrepareCanvas; virtual;
property AlignHorz: TAlignment read GetAlignHorz;
property AlignVert: TdxAlignmentVert read GetAlignVert;
property Canvas: TcxCanvas read GetCanvas;
property HotTrackBounds: TRect read GetHotTrackBounds;
property HotTrackStyles: TdxLayoutHotTrackStyles read GetHotTrackStyles;
property IsCustomization: Boolean read GetIsCustomization;
property IsDefaultColor: Boolean read GetIsDefaultColor;
property IsHotTrackable: Boolean read GetIsHotTrackable;
property IsTransparent: Boolean read GetIsTransparent;
property MultiLine: Boolean read GetMultiLine;
property Options: TdxLayoutLookAndFeelCaptionOptions read GetOptions;
property TextHeight: Integer read GetTextHeight;
property TextWidth: Integer read GetTextWidth;
public
function CalculateHeight: Integer; override;
function CalculateWidth: Integer; override;
property Color: TColor read GetColor;
property Font: TFont read GetFont;
property HotTracked: Boolean read FHotTracked write SetHotTracked;
property IsTextUnderlined: Boolean read GetIsTextUnderlined;
property Text: string read GetText;
property TextAreaBounds: TRect read GetTextAreaBounds;
property TextColor: TColor read GetTextColor;
property VisibleText: string read GetVisibleText;
end;
TdxCustomLayoutItemCaptionViewInfoClass = class of TdxCustomLayoutItemCaptionViewInfo;
TdxCustomLayoutItemViewInfo = class(TdxCustomLayoutElementViewInfo)
private
FOffsets: array[TdxLayoutSide] of Integer;
FCaptionViewInfo: TdxCustomLayoutItemCaptionViewInfo;
FContainerViewInfo: TdxLayoutControlViewInfo;
FParentViewInfo: TdxLayoutGroupViewInfo;
FElements: TObjectList;
FElementWithMouse: TdxCustomLayoutItemElementViewInfo;
FItem: TdxCustomLayoutItem;
FNotifyComponent: TcxFreeNotificator;
function GetMinHeight: Integer;
function GetMinWidth: Integer;
function GetHeight: Integer;
function GetWidth: Integer;
function GetAlignHorz: TdxLayoutAlignHorz;
function GetAlignVert: TdxLayoutAlignVert;
function GetBackgroundBounds: TRect;
function GetCanPaint: Boolean;
function GetIsAvailable: Boolean;
function GetIsCustomization: Boolean;
function GetIsDragged: Boolean;
function GetIsDraggedWithParent: Boolean;
function GetIsDragImagePainted: Boolean;
function GetOffset(ASide: TdxLayoutSide): Integer;
function GetOffsetsHeight: Integer;
function GetOffsetsWidth: Integer;
function GetSelected: Boolean;
function GetSelectionArea: TRect;
function GetSelectionBorderRect: TRect;
procedure SetElementWithMouse(Value: TdxCustomLayoutItemElementViewInfo);
procedure SetOffset(ASide: TdxLayoutSide; Value: Integer);
function CreateHitTest: TdxCustomLayoutItemHitTest;
protected
procedure DoCreateViewInfos; virtual;
procedure CreateViewInfos;
procedure DestroyViewInfos; virtual;
procedure FreeNotification(AComponent: TComponent); virtual;
function CanDrawBackground: Boolean; virtual;
function GetBackgroundColor: TColor; virtual;
function GetCaptionViewInfoClass: TdxCustomLayoutItemCaptionViewInfoClass; virtual; abstract;
function GetHitTestClass: TdxCustomLayoutItemHitTestClass; virtual; abstract;
function GetPainterClass: TdxCustomLayoutItemPainterClass; virtual; abstract;
function CalculateMinHeight: Integer;
function CalculateMinWidth: Integer;
function CalculateHeight: Integer;
function CalculateWidth: Integer;
function DoCalculateHeight(AIsMinHeight: Boolean): Integer; virtual;
function DoCalculateWidth(AIsMinWidth: Boolean): Integer; virtual;
function CalculateOffset(ASide: TdxLayoutSide): Integer; virtual;
function GetAreaPart(const P: TPoint): TdxLayoutAreaPart; virtual;
function GetActuallyVisible: Boolean; virtual;
function GetColor: TColor; virtual; abstract;
function GetCursor(X, Y: Integer): TCursor; virtual;
function GetElement(AIndex: Integer): TdxCustomLayoutItemElementViewInfo;
function GetElementCount: Integer;
function GetEnabled: Boolean; virtual;
function GetEnabledForWork: Boolean; virtual;
function GetIsDefaultColor: Boolean; virtual; abstract;
function GetIsTransparent: Boolean; virtual;
function GetOptions: TdxCustomLayoutLookAndFeelOptions; virtual; abstract;
function HasBackground: Boolean;
function HasCaption: Boolean; virtual; // #DG !!!
function HasBorder: Boolean; virtual;
procedure MouseEnter; dynamic;
procedure MouseLeave; dynamic;
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); dynamic;
procedure MouseMove(Shift: TShiftState; X, Y: Integer); dynamic;
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); dynamic;
function GetLayoutLookAndFeel: TdxCustomLayoutLookAndFeel; override;
// selections
procedure PaintSelectionLayer; virtual;
function IsParentLocked: Boolean;
function IsParentSelected: Boolean;
property ActuallyVisible: Boolean read GetActuallyVisible;
property BackgroundBounds: TRect read GetBackgroundBounds;
property CanPaint: Boolean read GetCanPaint; // todo: rename
property ContainerViewInfo: TdxLayoutControlViewInfo read FContainerViewInfo;
property ElementCount: Integer read GetElementCount;
property Elements[Index: Integer]: TdxCustomLayoutItemElementViewInfo read GetElement;
property ElementWithMouse: TdxCustomLayoutItemElementViewInfo read FElementWithMouse write SetElementWithMouse;
property IsAvailable: Boolean read GetIsAvailable;
property IsCustomization: Boolean read GetIsCustomization;
property IsDefaultColor: Boolean read GetIsDefaultColor;
property IsDragged: Boolean read GetIsDragged;
property IsDraggedWithParent: Boolean read GetIsDraggedWithParent;
property IsDragImagePainted: Boolean read GetIsDragImagePainted;
property IsTransparent: Boolean read GetIsTransparent;
property Item: TdxCustomLayoutItem read FItem;
property OffsetsHeight: Integer read GetOffsetsHeight;
property OffsetsWidth: Integer read GetOffsetsWidth;
property Options: TdxCustomLayoutLookAndFeelOptions read GetOptions;
property ParentViewInfo: TdxLayoutGroupViewInfo read FParentViewInfo;
public
constructor Create(AContainerViewInfo: TdxLayoutControlViewInfo;
AParentViewInfo: TdxLayoutGroupViewInfo; AItem: TdxCustomLayoutItem); virtual;
destructor Destroy; override;
procedure Calculate(const ABounds: TRect); override;
procedure CalculateTabOrders(var AAvailTabOrder: Integer); virtual; abstract;
function GetHitTest(const P: TPoint): TdxCustomLayoutHitTest; virtual;
function GetItemWithMouse(const P: TPoint): TdxCustomLayoutItem; virtual;
procedure ResetOffset(ASide: TdxLayoutSide);
property AlignHorz: TdxLayoutAlignHorz read GetAlignHorz;
property AlignVert: TdxLayoutAlignVert read GetAlignVert;
property CaptionViewInfo: TdxCustomLayoutItemCaptionViewInfo read FCaptionViewInfo;
property Color: TColor read GetColor;
property Enabled: Boolean read GetEnabled;
property EnabledForWork: Boolean read GetEnabledForWork;
property MinWidth: Integer read GetMinWidth;
property MinHeight: Integer read GetMinHeight;
property Width: Integer read GetWidth;
property Height: Integer read GetHeight;
property Offsets[ASide: TdxLayoutSide]: Integer read GetOffset write SetOffset;
property Selected: Boolean read GetSelected;
property SelectionBorderRect: TRect read GetSelectionBorderRect;
property SelectionArea: TRect read GetSelectionArea;
end;
{ ItemViewInfos }
{ TdxLayoutItemCaptionViewInfo }
TdxLayoutItemCaptionViewInfo = class(TdxCustomLayoutItemCaptionViewInfo)
private
function GetItem: TdxLayoutItem;
function GetItemViewInfo: TdxLayoutItemViewInfo;
protected
function GetAlignVert: TdxAlignmentVert; override;
function GetIsFixedWidth: Boolean; virtual;
function GetMultiLine: Boolean; override;
function GetTextAreaBounds: TRect; override;
property IsFixedWidth: Boolean read GetIsFixedWidth;
property Item: TdxLayoutItem read GetItem;
property ItemViewInfo: TdxLayoutItemViewInfo read GetItemViewInfo;
public
function CalculateWidth: Integer; override;
function CalculateMinWidth: Integer; override;
end;
TdxLayoutItemControlViewInfoClass = class of TdxLayoutItemControlViewInfo;
TdxLayoutItemControlViewInfo = class(TdxCustomLayoutItemElementViewInfo)
private
FControlBounds: TRect;
function GetBorderColor: TColor;
function GetBorderStyle: TdxLayoutBorderStyle;
function GetControl: TControl;
function GetItem: TdxLayoutItem;
function GetItemViewInfo: TdxLayoutItemViewInfo;
function GetOpaqueControl: Boolean;
protected
function GetVisible: Boolean; override;
function CalculateControlBounds: TRect; virtual;
function GetBorderWidth(ASide: TdxLayoutSide): Integer; virtual;
function GetControlAreaHeight(AControlHeight: Integer): Integer; virtual;
function GetControlAreaWidth(AControlWidth: Integer): Integer; virtual;
function HasBorder: Boolean;
property BorderWidths[ASide: TdxLayoutSide]: Integer read GetBorderWidth;
property Item: TdxLayoutItem read GetItem;
property ItemViewInfo: TdxLayoutItemViewInfo read GetItemViewInfo;
public
procedure Calculate(const ABounds: TRect); override;
procedure CalculateTabOrder(var AAvailTabOrder: Integer); virtual;
function CalculateMinHeight: Integer; override;
function CalculateMinWidth: Integer; override;
function CalculateHeight: Integer; override;
function CalculateWidth: Integer; override;
property BorderColor: TColor read GetBorderColor;
property BorderStyle: TdxLayoutBorderStyle read GetBorderStyle;
property Control: TControl read GetControl;
property ControlBounds: TRect read FControlBounds;
property OpaqueControl: Boolean read GetOpaqueControl;
end;
TdxLayoutItemViewInfo = class(TdxCustomLayoutItemViewInfo)
private
FControlViewInfo: TdxLayoutItemControlViewInfo;
function GetCaptionViewInfo: TdxLayoutItemCaptionViewInfo;
function GetItem: TdxLayoutItem;
function GetOptionsEx: TdxLayoutLookAndFeelItemOptions;
function GetDesignSelectorRect: TRect;
protected
procedure DoCreateViewInfos; override;
function GetCaptionViewInfoClass: TdxCustomLayoutItemCaptionViewInfoClass; override;
function GetControlViewInfoClass: TdxLayoutItemControlViewInfoClass; virtual;
function GetHitTestClass: TdxCustomLayoutItemHitTestClass; override;
function GetPainterClass: TdxCustomLayoutItemPainterClass; override;
procedure CalculateViewInfosBounds(var ACaptionBounds, AControlBounds: TRect); virtual;
function DoCalculateHeight(AIsMinHeight: Boolean): Integer; override;
function DoCalculateWidth(AIsMinWidth: Boolean): Integer; override;
function GetAutoControlAlignment: Boolean; virtual;
function GetCaptionLayout: TdxCaptionLayout; virtual;
function GetColor: TColor; override;
function GetContentBounds: TRect; virtual;
function GetControlOffsetHorz: Integer; virtual;
function GetControlOffsetVert: Integer; virtual;
function GetIsDefaultColor: Boolean; override;
function GetOptions: TdxCustomLayoutLookAndFeelOptions; override;
function HasControl: Boolean; virtual;
// selections
procedure PaintSelectionLayer; override;
function PtInDesignSelectorRect(const P: TPoint): Boolean;
property ControlOffsetHorz: Integer read GetControlOffsetHorz;
property ControlOffsetVert: Integer read GetControlOffsetVert;
property Item: TdxLayoutItem read GetItem;
property Options: TdxLayoutLookAndFeelItemOptions read GetOptionsEx;
public
procedure Calculate(const ABounds: TRect); override;
procedure CalculateTabOrders(var AAvailTabOrder: Integer); override;
property AutoControlAlignment: Boolean read GetAutoControlAlignment;
property CaptionLayout: TdxCaptionLayout read GetCaptionLayout;
property CaptionViewInfo: TdxLayoutItemCaptionViewInfo read GetCaptionViewInfo;
property ContentBounds: TRect read GetContentBounds;
property ControlViewInfo: TdxLayoutItemControlViewInfo read FControlViewInfo;
property DesignSelectorRect: TRect read GetDesignSelectorRect;
end;
{ GroupViewInfos }
{ TdxLayoutGroupCaptionViewInfo }
TdxLayoutGroupCaptionViewInfo = class(TdxCustomLayoutItemCaptionViewInfo)
protected
function GetAlignVert: TdxAlignmentVert; override;
function GetMultiLine: Boolean; override;
public
function CalculateMinWidth: Integer; override;
end;
TItemInfo = record
ViewInfo: TdxCustomLayoutItemViewInfo;
AlignHorz: TdxLayoutAlignHorz;
CalculatedWidth, MinWidth, Width, Height: Integer;
Bounds: TRect;
Calculated: Boolean;
end;
TItemInfos = array of TItemInfo;
TdxLayoutGroupViewInfoSpecific = class
private
FGroupViewInfo: TdxLayoutGroupViewInfo;
FItemInfos: TItemInfos;
procedure PrepareItemInfos;
procedure CalculateItemViewInfos;
function GetContainer: TdxCustomLayoutControl;
function GetItemOffset: Integer;
function GetItemViewInfo(Index: Integer): TdxCustomLayoutItemViewInfo;
function GetItemViewInfoCount: Integer;
function GetLayoutDirection: TdxLayoutDirection;
protected
// Drawing
procedure DrawSpecificPart(ACanvas: TcxCanvas); virtual; // !!!
procedure DrawSpecificBackground(ACanvas: TcxCanvas); virtual; // !!!
// Calculating
procedure CalculateItemsHorizontalBounds(const AItemsAreaBounds: TRect); virtual;
procedure CalculateItemsVerticalBounds(const AItemsAreaBounds: TRect); virtual;
procedure CalculateTabOrders(var ATabOrder: Integer); virtual;
// Dragging
function GetAreaPart(const P: TPoint): TdxLayoutAreaPart; virtual;
function GetHitTest(const P: TPoint): TdxCustomLayoutHitTest; virtual;
// Sizes
procedure ConvertCoords(var R: TRect); virtual;
function GetCustomHeight(AIsMinHeight: Boolean): Integer; virtual;
function GetCustomWidth(AIsMinWidth: Boolean): Integer; virtual;
function GetItemAlignHorz(AViewInfo: TdxCustomLayoutItemViewInfo): TdxLayoutAlignHorz; virtual; abstract;
function GetItemAlignVert(AViewInfo: TdxCustomLayoutItemViewInfo): TdxLayoutAlignVert; virtual; abstract;
function GetItemHeight(AViewInfo: TdxCustomLayoutItemViewInfo): Integer; virtual; abstract;
function GetItemWidth(AViewInfo: TdxCustomLayoutItemViewInfo): Integer; virtual; abstract;
function GetItemMinHeight(AViewInfo: TdxCustomLayoutItemViewInfo): Integer; virtual; abstract;
function GetItemMinWidth(AViewInfo: TdxCustomLayoutItemViewInfo): Integer; virtual; abstract;
function GetItemsAreaOffset(ASide: TdxLayoutSide): Integer; virtual;
// Selection
procedure AddSelectionControls; virtual;
procedure RemoveSelectionControls; virtual;
// Specific Objects
procedure CreateSpecificControls; virtual;
procedure DestroySpecificControls; virtual;
procedure CreateViewInfos; virtual;
procedure SetControlVisibility; virtual;
property Container: TdxCustomLayoutControl read GetContainer;
property GroupViewInfo: TdxLayoutGroupViewInfo read FGroupViewInfo;
property ItemOffset: Integer read GetItemOffset;
property ItemViewInfoCount: Integer read GetItemViewInfoCount;
property ItemViewInfos[Index: Integer]: TdxCustomLayoutItemViewInfo read GetItemViewInfo;
property LayoutDirection: TdxLayoutDirection read GetLayoutDirection;
public
constructor Create(AGroupViewInfo: TdxLayoutGroupViewInfo); virtual;
destructor Destroy; override;
procedure Calculate(const AItemsAreaBounds: TRect); virtual;
procedure CalculateItemsBounds(AItemsAreaBounds: TRect);
function CanDrawBackground: Boolean; virtual;
function GetItemsAreaHeight(AIsMinHeight: Boolean): Integer; virtual;
function GetItemsAreaWidth(AIsMinWidth: Boolean): Integer; virtual;
function IsAtInsertionPos(const R: TRect; const P: TPoint): Boolean; virtual; abstract;
function AllowDrawChild(AChild: TdxCustomLayoutItem): Boolean; virtual;
function AllowChildHasBorder: Boolean; virtual;
end;
TdxLayoutGroupViewInfoHorizontalSpecific = class(TdxLayoutGroupViewInfoSpecific)
protected
function GetItemAlignHorz(AViewInfo: TdxCustomLayoutItemViewInfo): TdxLayoutAlignHorz; override;
function GetItemAlignVert(AViewInfo: TdxCustomLayoutItemViewInfo): TdxLayoutAlignVert; override;
function GetItemHeight(AViewInfo: TdxCustomLayoutItemViewInfo): Integer; override;
function GetItemWidth(AViewInfo: TdxCustomLayoutItemViewInfo): Integer; override;
function GetItemMinHeight(AViewInfo: TdxCustomLayoutItemViewInfo): Integer; override;
function GetItemMinWidth(AViewInfo: TdxCustomLayoutItemViewInfo): Integer; override;
public
function IsAtInsertionPos(const R: TRect; const P: TPoint): Boolean; override;
end;
TdxLayoutGroupViewInfoVerticalSpecific = class(TdxLayoutGroupViewInfoSpecific)
protected
procedure ConvertCoords(var R: TRect); override;
function GetItemAlignHorz(AViewInfo: TdxCustomLayoutItemViewInfo): TdxLayoutAlignHorz; override;
function GetItemAlignVert(AViewInfo: TdxCustomLayoutItemViewInfo): TdxLayoutAlignVert; override;
function GetItemHeight(AViewInfo: TdxCustomLayoutItemViewInfo): Integer; override;
function GetItemWidth(AViewInfo: TdxCustomLayoutItemViewInfo): Integer; override;
function GetItemMinHeight(AViewInfo: TdxCustomLayoutItemViewInfo): Integer; override;
function GetItemMinWidth(AViewInfo: TdxCustomLayoutItemViewInfo): Integer; override;
public
function GetItemsAreaHeight(AIsMinHeight: Boolean): Integer; override;
function GetItemsAreaWidth(AIsMinWidth: Boolean): Integer; override;
function IsAtInsertionPos(const R: TRect; const P: TPoint): Boolean; override;
end;
TdxLayoutTabbedGroupTabControl = class(TcxTabControl)
private
procedure WMNCHitTest(var Message: TWMNCHitTest); message WM_NCHITTEST;
protected
procedure BoundsChanged; override;
function GetDesignHitTest(X, Y: Integer; Shift: TShiftState): Boolean; override;
end;
TdxTabControlElementViewInfo = class(TdxCustomLayoutItemElementViewInfo)
private
FTabControl: TdxLayoutTabbedGroupTabControl;
protected
function GetVisible: Boolean; override;
procedure MouseEnter; override;
procedure MouseLeave; 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;
end;
TdxLayoutGroupViewInfoTabbedSpecific = class(TdxLayoutGroupViewInfoHorizontalSpecific)
private
FTabControl: TdxLayoutTabbedGroupTabControl;
FTabControlElementViewInfo: TdxTabControlElementViewInfo;
procedure ActiveTabChanged(ASender: TObject);
protected
// Drawing
procedure DrawSpecificPart(ACanvas: TcxCanvas); override;
procedure DrawSpecificBackground(ACanvas: TcxCanvas); override;
// Calculating
procedure CalculateItemsHorizontalBounds(const AItemsAreaBounds: TRect); override;
procedure CalculateItemsVerticalBounds(const AItemsAreaBounds: TRect); override;
procedure CalculateTabOrders(var ATabOrder: Integer); override;
// Dragging
function GetAreaPart(const P: TPoint): TdxLayoutAreaPart; override;
function GetHitTest(const P: TPoint): TdxCustomLayoutHitTest; override;
// Sizes
function GetCustomHeight(AIsMinHeight: Boolean): Integer; override;
function GetCustomWidth(AIsMinWidth: Boolean): Integer; override;
function GetItemsAreaOffset(ASide: TdxLayoutSide): Integer; override;
// Specific Objects
procedure CreateSpecificControls; override;
procedure DestroySpecificControls; override;
procedure CreateViewInfos; override;
procedure SetControlVisibility; override;
procedure CreateTabControl;
procedure DestroyTabControl;
function HasTabControl: Boolean;
public
procedure Calculate(const AItemsAreaBounds: TRect); override;
function AllowDrawChild(AChild: TdxCustomLayoutItem): Boolean; override;
function AllowChildHasBorder: Boolean; override;
function CanDrawBackground: Boolean; override;
end;
TdxLayoutGroupViewInfo = class(TdxCustomLayoutItemViewInfo)
private
FOffsetsCalculated: Boolean;
FItemOffset: Integer;
FItemsAreaOffsetHorz: Integer;
FItemsAreaOffsetVert: Integer;
FItemViewInfos: TObjectList;
FSpecific: TdxLayoutGroupViewInfoSpecific;
function GetBorderBounds(ASide: TdxLayoutSide): TRect;
function GetBorderRestSpaceBounds(ASide: TdxLayoutSide): TRect;
function GetBordersHeight: Integer;
function GetBordersWidth: Integer;
function GetCaptionViewInfo: TdxLayoutGroupCaptionViewInfo;
function GetGroup: TdxLayoutGroup;
function GetIsLocked: Boolean;
function GetItemViewInfo(Index: Integer): TdxCustomLayoutItemViewInfo;
function GetItemViewInfoCount: Integer;
function GetLayoutDirection: TdxLayoutDirection;
function GetOptionsEx: TdxLayoutLookAndFeelGroupOptions;
function GetOffset(Index: Integer): Integer;
procedure CreateItemViewInfos;
procedure CreateSpecific;
procedure DestroyItemViewInfos;
procedure DestroySpecific;
protected
FCaptionAreaBounds: TRect;
FClientAreaBounds: TRect;
FItemsAreaBounds: TRect;
procedure DoCreateViewInfos; override;
procedure DestroyViewInfos; override;
procedure FreeNotification(AComponent: TComponent); override;
// Classes
function GetCaptionViewInfoClass: TdxCustomLayoutItemCaptionViewInfoClass; override;
function GetHitTestClass: TdxCustomLayoutItemHitTestClass; override;
function GetPainterClass: TdxCustomLayoutItemPainterClass; override;
// Drawing attributes
function GetBackgroundColor: TColor; override;
function GetColor: TColor; override;
function GetIsDefaultColor: Boolean; override;
function GetOptions: TdxCustomLayoutLookAndFeelOptions; override;
// Calculating
function DoCalculateHeight(AIsMinHeight: Boolean = False): Integer; override;
function DoCalculateWidth(AIsMinWidth: Boolean = False): Integer; override;
// Dragging
function GetAreaPart(const P: TPoint): TdxLayoutAreaPart; override;
// Conditions
function HasCaption: Boolean; override;
function HasBorder: Boolean; override;
// TdxLayoutGroupViewInfo methods
// Calculating
procedure CalculateCaptionViewInfoBounds; virtual;
procedure CalculateClientBounds; virtual;
procedure CalculateItemsAreaBounds; virtual;
procedure CalculateOffsets;
// Sizes
function GetClientAreaBounds(const ABounds: TRect): TRect;
function GetItemAreaBounds(const AClientRect: TRect): TRect;
function GetBorderWidth(ASide: TdxLayoutSide): Integer; virtual;
function GetHeight(AItemsAreaHeight: Integer): Integer; virtual;
function GetWidth(AItemsAreaWidth: Integer): Integer; virtual;
function GetMinVisibleHeight: Integer; virtual;
function GetMinVisibleWidth: Integer; virtual;
function GetRestSpaceBounds: TRect; virtual;
// Conditions
function AllowChildHasBorder: Boolean;
function HasBoundsFrame: Boolean; virtual;
function UseItemOffset: Boolean; virtual;
function UseItemsAreaOffsets: Boolean; virtual;
// Classes
function GetItemViewInfoClass(AItem: TdxCustomLayoutItem): TdxCustomLayoutItemViewInfoClass; virtual;
function GetSpecificClass: TdxLayoutGroupViewInfoSpecificClass; virtual;
// Selections
procedure PaintSelectionLayer; override;
property ItemOffset: Integer index 0 read GetOffset write FItemOffset;
property ItemsAreaOffsetHorz: Integer index 1 read GetOffset write FItemsAreaOffsetHorz;
property ItemsAreaOffsetVert: Integer index 2 read GetOffset write FItemsAreaOffsetVert;
property MinVisibleHeight: Integer read GetMinVisibleHeight;
property MinVisibleWidth: Integer read GetMinVisibleWidth;
property RestSpaceBounds: TRect read GetRestSpaceBounds;
property Group: TdxLayoutGroup read GetGroup;
property LayoutDirection: TdxLayoutDirection read GetLayoutDirection;
property Options: TdxLayoutLookAndFeelGroupOptions read GetOptionsEx;
property Specific: TdxLayoutGroupViewInfoSpecific read FSpecific;
public
procedure Calculate(const ABounds: TRect); override;
procedure CalculateTabOrders(var AAvailTabOrder: Integer); override;
function GetHitTest(const P: TPoint): TdxCustomLayoutHitTest; override;
function GetItemWithMouse(const P: TPoint): TdxCustomLayoutItem; override;
function GetInsertionPos(const P: TPoint): Integer; virtual;
property BorderBounds[ASide: TdxLayoutSide]: TRect read GetBorderBounds;
property BorderRestSpaceBounds[ASide: TdxLayoutSide]: TRect read GetBorderRestSpaceBounds;
property BorderWidths[ASide: TdxLayoutSide]: Integer read GetBorderWidth;
property BordersHeight: Integer read GetBordersHeight;
property BordersWidth: Integer read GetBordersWidth;
property CaptionViewInfo: TdxLayoutGroupCaptionViewInfo read GetCaptionViewInfo;
property ClientBounds: TRect read FClientAreaBounds;
property IsLocked: Boolean read GetIsLocked;
property ItemsAreaBounds: TRect read FItemsAreaBounds;
property ItemViewInfoCount: Integer read GetItemViewInfoCount;
property ItemViewInfos[Index: Integer]: TdxCustomLayoutItemViewInfo read GetItemViewInfo;
end;
// control
TdxLayoutControlViewInfo = class(TdxCustomLayoutControlHandler)
private
FCanvas: TcxCanvas;
FContentBounds: TRect;
FItemsViewInfo: TdxLayoutGroupViewInfo;
FSelectionLayer: TdxSelectionLayer;
FIsDragImagePainted: Boolean;
procedure CreateSelectionLayer;
procedure BuildSelectionLayer;
function GetClientHeight: Integer;
function GetClientWidth: Integer;
function GetContentHeight: Integer;
function GetContentWidth: Integer;
function GetLayoutLookAndFeel: TdxCustomLayoutLookAndFeel;
function GetSelectionLayer: TdxSelectionLayer;
protected
procedure CreateViewInfos; virtual;
procedure DestroyViewInfos; virtual;
function GetItemsViewInfoClass: TdxLayoutGroupViewInfoClass; virtual;
procedure RecreateViewInfos;
procedure AlignItems; virtual;
procedure AutoAlignControls; virtual;
procedure CalculateItemsViewInfo; virtual;
procedure CalculateTabOrders; virtual;
function GetIsTransparent: Boolean; virtual;
function HasBackground: Boolean;
function NeedHighlightRoot: Boolean;
procedure PrepareData; virtual;
procedure ResetContentBounds;
function GetCanvas: TcxCanvas; virtual;
function GetClientBounds: TRect; virtual;
function GetContentBounds: TRect; virtual;
property Canvas: TcxCanvas read GetCanvas;
property IsDragImagePainted: Boolean read FIsDragImagePainted write FIsDragImagePainted;
property IsTransparent: Boolean read GetIsTransparent;
property SelectionLayer: TdxSelectionLayer read GetSelectionLayer;
public
constructor Create(AControl: TdxCustomLayoutControl); override;
destructor Destroy; override;
procedure Calculate; virtual;
procedure DoCalculateTabOrders; virtual;
function GetHitTest(const P: TPoint): TdxCustomLayoutHitTest; overload; virtual;
function GetHitTest(X, Y: Integer): TdxCustomLayoutHitTest; overload;
function GetItemWithMouse(const P: TPoint): TdxCustomLayoutItem;
property ClientBounds: TRect read GetClientBounds;
property ClientHeight: Integer read GetClientHeight;
property ClientWidth: Integer read GetClientWidth;
property ContentBounds: TRect read GetContentBounds;
property ContentHeight: Integer read GetContentHeight;
property ContentWidth: Integer read GetContentWidth;
property ItemsViewInfo: TdxLayoutGroupViewInfo read FItemsViewInfo;
property LayoutLookAndFeel: TdxCustomLayoutLookAndFeel read GetLayoutLookAndFeel;
end;
{ other }
TdxLayoutCustomizeListBox = class(TcxCustomizeListBox)
private
FControl: TdxCustomLayoutControl;
function GetDragAndDropItemObject: TdxCustomLayoutItem;
protected
procedure BeginDragAndDrop; override;
property DragAndDropItemObject: TdxCustomLayoutItem read GetDragAndDropItemObject;
public
property Control: TdxCustomLayoutControl read FControl write FControl;
end;
{ TdxLayoutRunTimeSelectionHelper }
TdxLayoutRunTimeSelectionHelper = class(TPersistent, IdxLayoutSelectionHelper)
private
FListeners: TList;
FOwner: TPersistent;
FRefCount: Integer;
FSelectionList: TcxComponentList;
function GetComponent: TComponent;
procedure SelectionListNotifyHandler(Sender: TObject; AComponent: TComponent; AAction: TListNotification);
procedure SelectionListChangedHandler(Sender: TObject; AComponent: TComponent; AAction: TcxComponentCollectionNotification);
protected
function GetComponentClass(AComponent: TComponent): TComponentClass;
procedure NotifyListeners(AList: TList; AAction: TdxLayoutSelectionAction);
procedure SelectionListNotify(AComponent: TComponent; AAction: TListNotification);
//IUnknown
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
property Component: TComponent read GetComponent;
property Listeners: TList read FListeners;
public
constructor Create(AOwner: TPersistent); virtual;
destructor Destroy; override;
// IdxLayoutControlSelectionController
procedure AddSelectionChangedListener(AListener: TPersistent); virtual;
procedure RemoveSelectionChangedListener(AListener: TPersistent); virtual;
//IcxLayoutControlDesignerHelper
function CanDeleteComponent(AComponent: TComponent): Boolean; virtual;
procedure ClearSelection; virtual;
procedure GetSelection(AList: TList); virtual;
function IsComponentSelected(AComponent: TPersistent): Boolean; virtual;
procedure SelectComponent(AComponent: TPersistent; AShift: TShiftState = []); virtual;
procedure SetSelection(AList: TList); virtual;
function UniqueName(const BaseName: string): string; virtual;
property Owner: TPersistent read FOwner;
end;
TdxLayoutRunTimeSelectionHelperClass = class of TdxLayoutRunTimeSelectionHelper;
var
dxLayoutSelectionHelperClass: TdxLayoutRunTimeSelectionHelperClass;
implementation
{$R *.res}
uses
Types, TypInfo, Menus, Registry, Math, Variants,
{$IFDEF DELPHI7}
UxTheme, Themes,
{$ENDIF}
cxContainer, dxOffice11, dxLayoutControlAdapters, dxLayoutCustomizeForm, dxLayoutStrs;
type
TControlAccess = class(TControl);
TdxCustomLayoutLookAndFeelAccess = class(TdxCustomLayoutLookAndFeel);
TcxPCCustomPainterAccess = class(TcxPCCustomPainter);
const
ScrollStep = 10;
dxLayoutSelectionDefaultColor: TColor = $EDC8A3;
dxLayoutControlSelectionDefaultColor: TColor = $582801;
dxLayoutSelectionBorderDefaultColor: TColor = $BD8753;
dxLayoutSelectionDefaultAlphaChannel: Byte = 80;
dxLayoutSelectionBorderMarkerInnerDefaultColor: TColor = clWhite;
dxLayoutHiddenGroupBackgroundDefaultColor: TColor = $F0E3D1;
dxLayoutHiddenGroupBorderDefaultColor: TColor = $C8BCB5;
dxLayoutSelectionOffset: Cardinal = 2;
dxSelectionMarkerWidth: Cardinal = 5;
dxLayoutDestinationColor = $D0D0EE;
dxLayoutDestinationBorderColor = $000059;
procedure dxDrawSelectionMarkers(ACanvas: TcxCanvas; const ABorderBounds: TRect;
ABorderColor, ABorderMarkerInnerColor: TColor; AMarkerWidth: Integer);
procedure DrawSelectionBorderMarker(const P: TPoint);
var
R: TRect;
begin
R.TopLeft := P;
R.BottomRight := P;
InflateRect(R, (AMarkerWidth - 1) div 2, (AMarkerWidth - 1) div 2);
Inc(R.Bottom);
Inc(R.Right);
ACanvas.Brush.Color := ABorderMarkerInnerColor;
ACanvas.Pen.Color := ABorderColor;
ACanvas.Canvas.Rectangle(R);
ACanvas.ExcludeClipRect(R);
end;
var
AMiddleX: Integer;
AMiddleY: Integer;
begin
with ABorderBounds do
begin
DrawSelectionBorderMarker(TopLeft);
DrawSelectionBorderMarker(Point(Right - 1, Bottom - 1));
DrawSelectionBorderMarker(Point(Left, Bottom - 1));
DrawSelectionBorderMarker(Point(Right - 1, Top));
AMiddleX := (Left + Right - 1) div 2;
AMiddleY := (Top + Bottom - 1) div 2;
DrawSelectionBorderMarker(Point(AMiddleX, Top));
DrawSelectionBorderMarker(Point(AMiddleX, Bottom - 1));
DrawSelectionBorderMarker(Point(Left, AMiddleY));
DrawSelectionBorderMarker(Point(Right - 1, AMiddleY));
end;
end;
type
{ TdxCustomizationCanvas }
TdxCustomizationCanvasState = record
PrevCanvas: TCanvas;
PrevDC: THandle;
NewDC: THandle;
NewDCIndex: Integer;
end;
TdxCustomizationCanvasStates = array of TdxCustomizationCanvasState;
TdxCustomizationCanvas = class(TcxCanvas)
private
FCounter: Integer;
FSavedDCs: TdxCustomizationCanvasStates;
function HandleValid: Boolean;
public
constructor Create; reintroduce;
destructor Destroy; override;
procedure BeginPaint(ADC: THandle); overload;
procedure BeginPaint(ACanvas: TCanvas); overload;
procedure EndPaint;
end;
{ TdxCustomSatelliteControlItem }
TdxSatelliteControls = class;
TdxCustomSatelliteControlItem = class(TComponent)
private
FControl: TControl;
FOwner: TdxSatelliteControls;
protected
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
public
constructor Create(AOwner: TdxSatelliteControls; AControl: TControl); reintroduce; virtual;
destructor Destroy; override;
property Control: TControl read FControl;
property Owner: TdxSatelliteControls read FOwner;
end;
TdxCustomSatelliteControlItemClass = class of TdxCustomSatelliteControlItem;
{ TdxControlDesignSelectorItem }
TdxControlDesignSelectorItem = class(TdxCustomSatelliteControlItem)
private
FChildren: TcxComponentList;
FDefaultControlWndProc: TWndMethod;
FLayoutItem: TdxLayoutItem;
FParent: TdxControlDesignSelectorItem;
FSelectorBounds: TRect;
function GetSelectorBoundsForChild(AChild: TdxControlDesignSelectorItem): TRect;
procedure SetLayoutItem(AValue: TdxLayoutItem);
procedure SetSelectorBounds(const AValue: TRect);
protected
procedure ControlWndProc(var Message: TMessage);
procedure CheckChildren;
procedure ParentCheckChildren;
function IsActive: Boolean;
function IsValid: Boolean;
// Draw
function CanDrawDesignSelector: Boolean;
procedure DoDrawDesignSelector(DC: HDC);
procedure DrawDesignSelector(DC: HDC);
property Parent: TdxControlDesignSelectorItem read FParent write FParent;
public
constructor Create(AOwner: TdxSatelliteControls; AControl: TControl); reintroduce; override;
destructor Destroy; override;
property SelectorBounds: TRect read FSelectorBounds write SetSelectorBounds;
property LayoutItem: TdxLayoutItem read FLayoutItem write SetLayoutItem;
end;
{ TdxCustomizationControlItem }
TdxCustomizationControlItem = class(TdxCustomSatelliteControlItem)
private
FPrevEnabled: Boolean;
function GetControl: TWinControl;
public
constructor Create(AOwner: TdxSatelliteControls; AControl: TControl); reintroduce; override;
destructor Destroy; override;
property Control: TWinControl read GetControl;
end;
{ TdxSatelliteControls }
TdxSatelliteControls = class(TcxComponentList)
private
function GetItem(Index: Integer): TdxCustomSatelliteControlItem;
public
function AddControl(AControl: TControl; AItemClass: TdxCustomSatelliteControlItemClass): TdxCustomSatelliteControlItem;
function FindByControl(AControl: TControl): Integer;
procedure RemoveControl(AControl: TControl);
property Items[Index: Integer]: TdxCustomSatelliteControlItem read GetItem; default;
end;
{ TdxLayoutControlAdapterDefs }
PControlAdapterRecord = ^TControlAdapterRecord;
TControlAdapterRecord = record
ControlClass: TControlClass;
AdapterClass: TdxCustomLayoutControlAdapterClass;
end;
TdxLayoutControlAdapterDefs = class
private
FItems: TList;
function GetCount: Integer;
function GetItem(Index: Integer): TControlAdapterRecord;
procedure ClearItems;
protected
procedure Delete(AIndex: Integer);
property Count: Integer read GetCount;
property Items[Index: Integer]: TControlAdapterRecord read GetItem;
public
constructor Create;
destructor Destroy; override;
function GetAdapterClass(AControl: TControl): TdxCustomLayoutControlAdapterClass;
procedure Register(AControlClass: TControlClass;
AAdapterClass: TdxCustomLayoutControlAdapterClass);
procedure Unregister(AControlClass: TControlClass;
AAdapterClass: TdxCustomLayoutControlAdapterClass);
end;
var
FdxLayoutControlAdapterDefs: TdxLayoutControlAdapterDefs;
FGlobalCanvas: TdxCustomizationCanvas;
function dxLayoutControlAdapterDefs: TdxLayoutControlAdapterDefs;
begin
if FdxLayoutControlAdapterDefs = nil then
FdxLayoutControlAdapterDefs := TdxLayoutControlAdapterDefs.Create;
Result := FdxLayoutControlAdapterDefs;
end;
function dxGetCenterAreaBounds(const AItemBounds: TRect): TRect;
begin
Result := AItemBounds;
with Result do
InflateRect(Result, -(Right - Left) div 4, -(Bottom - Top) div 4);
end;
function dxGlobalCanvas: TdxCustomizationCanvas;
begin
if FGlobalCanvas = nil then
FGlobalCanvas := TdxCustomizationCanvas.Create;
Result := FGlobalCanvas;
end;
{ TdxLayoutOffsets }
function TdxLayoutOffsets.GetValue(Index: Integer): Integer;
begin
case Index of
1: Result := FBottom;
2: Result := FLeft;
3: Result := FRight;
4: Result := FTop;
else
Result := 0;
end;
end;
procedure TdxLayoutOffsets.SetValue(Index: Integer; Value: Integer);
begin
if Value < 0 then Value := 0;
if GetValue(Index) <> Value then
begin
case Index of
1: FBottom := Value;
2: FLeft := Value;
3: FRight := Value;
4: FTop := Value;
end;
Changed;
end;
end;
{ TdxCustomLayoutControlHandler }
constructor TdxCustomLayoutControlHandler.Create(AControl: TdxCustomLayoutControl);
begin
inherited Create;
FControl := AControl;
end;
function TdxCustomLayoutControlHandler.GetViewInfo: TdxLayoutControlViewInfo;
begin
Result := FControl.ViewInfo;
end;
{ TdxCustomLayoutControl }
constructor TdxCustomLayoutControl.Create(AOwner: TComponent);
begin
inherited;
ControlStyle := ControlStyle + [csAcceptsControls, csOpaque];
{$IFDEF DELPHI7}
ParentBackground := False;
{$ENDIF}
{
with cxLookAndFeel do
begin
Kind := lfStandard;
NativeStyle := True;
end;
}
TabStop := False;
Width := 300;
Height := 250;
FAbsoluteItems := TcxComponentList.Create;
FAvailableItems := TcxComponentList.Create;
FAvailableItems.OnComponentListChanged := AvailableItemListChanged;
FCustomizationControls := TdxSatelliteControls.Create(True);
FOptionsStoring := TdxStoringOptions.Create;
FStoredStream := TMemoryStream.Create;
FAutoControlAlignment := True;
FAutoControlTabOrders := True;
FHighlightRoot := True;
FShowDesignSelectors := True;
FBoldFont := TFont.Create;
RefreshBoldFont;
FCustomizeFormClass := TdxLayoutControlCustomizeForm;
GetLayoutLookAndFeel.AddUser(Self);
InitializeSubControlsCxLookAndFeel;
CreateRootGroup;
//FGroups.UseIndent := False;
CreateConstraints;
FSelectionHelper := dxLayoutSelectionHelperClass.Create(Self);
FSelectionHelper.AddSelectionChangedListener(Self);
FCustomizeAvailableItemsViewKind := oivkTree;
end;
destructor TdxCustomLayoutControl.Destroy;
begin
FSelectionHelper.RemoveSelectionChangedListener(Self);
Customization := False;
FSelectionHelper := nil;
if not IsDesigning then
Store;
SetRootGroup(nil);
LayoutLookAndFeel := nil;
GetLayoutLookAndFeel.RemoveUser(Self);
DestroyConstraints;
dxLayoutTextMetrics.Unregister(FBoldFont);
dxLayoutTextMetrics.Unregister(Font);
FreeAndNil(FBoldFont);
FreeAndNil(FStoredStream);
FreeAndNil(FOptionsStoring);
FreeAndNil(FCustomizationControls);
FAvailableItems.OwnsObjects := True;
FreeAndNil(FAvailableItems);
FreeAndNil(FAbsoluteItems);
inherited;
end;
procedure TdxCustomLayoutControl.BeginDragAndDrop;
begin
DragAndDropState := ddsInProcess;
inherited;
end;
function TdxCustomLayoutControl.GetAbsoluteItem(Index: Integer): TdxCustomLayoutItem;
begin
Result := TdxCustomLayoutItem(FAbsoluteItems[Index]);
end;
function TdxCustomLayoutControl.GetAbsoluteItemCount: Integer;
begin
Result := FAbsoluteItems.Count;
end;
function TdxCustomLayoutControl.GetAlignmentConstraint(Index: Integer): TdxLayoutAlignmentConstraint;
begin
Result := FAlignmentConstraints[Index];
end;
function TdxCustomLayoutControl.GetAlignmentConstraintCount: Integer;
begin
Result := FAlignmentConstraints.Count;
end;
function TdxCustomLayoutControl.GetAllowDrop: Boolean;
begin
Result := IsDesigning;
end;
function TdxCustomLayoutControl.GetAvailableItem(Index: Integer): TdxCustomLayoutItem;
begin
Result := TdxCustomLayoutItem(FAvailableItems[Index]);
end;
function TdxCustomLayoutControl.GetAvailableItemCount: Integer;
begin
Result := FAvailableItems.Count;
end;
function TdxCustomLayoutControl.GetContentBounds: TRect;
begin
Result := ViewInfo.ContentBounds;
end;
function TdxCustomLayoutControl.GetOccupiedClientWidth: Integer;
begin
Result := ViewInfo.ItemsViewInfo.CalculateWidth;
end;
function TdxCustomLayoutControl.GetOccupiedClientHeight: Integer;
begin
Result := ViewInfo.ItemsViewInfo.CalculateHeight;
end;
function TdxCustomLayoutControl.GetSelectedControlCount: Integer;
var
AList: TList;
begin
AList := TList.Create;
try
GetSelection(AList);
Result := AList.Count;
finally
AList.Free;
end;
end;
function TdxCustomLayoutControl.GetLayoutDirection: TdxLayoutDirection;
begin
Result := FRootGroup.LayoutDirection;
end;
function TdxCustomLayoutControl.GetAutoContentSizes: TdxLayoutAutoContentSizes;
begin
Result := TdxLayoutAutoContentSizes(FRootGroup.AutoAligns);
end;
procedure TdxCustomLayoutControl.SetAutoContentSizes(Value: TdxLayoutAutoContentSizes);
begin
FRootGroup.AutoAligns := TdxLayoutAutoAligns(Value);
end;
procedure TdxCustomLayoutControl.SetAutoControlAlignment(Value: Boolean);
begin
if FAutoControlAlignment <> Value then
begin
FAutoControlAlignment := Value;
LayoutChanged;
end;
end;
procedure TdxCustomLayoutControl.SetAutoControlTabOrders(Value: Boolean);
begin
if FAutoControlTabOrders <> Value then
begin
FAutoControlTabOrders := Value;
LayoutChanged;
end;
end;
procedure TdxCustomLayoutControl.SetCustomization(Value: Boolean);
begin
if (FCustomization <> Value) and (not Value or HandleAllocated) then
begin
if Value then
begin
FCustomizeForm := TdxLayoutControlCustomizeFormClass(CustomizeFormClass).Create(nil);
TdxLayoutControlCustomizeForm(FCustomizeForm).Control := Self;
FCustomizeForm.Show;
FCustomization := True;
UpdateCustomizationControls;
end
else
begin
FCustomization := False;
with FCustomizeForm do
if not (csDestroying in ComponentState) then
Free;
if not IsDesigning then
FSelectionHelper.ClearSelection;
if not IsDesigning then
FSelectionHelper.ClearSelection;
FCustomizationControls.Clear;
end;
LayoutChanged;
DoCustomization;
end
else
if FCustomization and HandleAllocated then
FCustomizeForm.BringToFront;
end;
procedure TdxCustomLayoutControl.SetCustomizeAvailableItemsViewKind(Value: TdxLayoutAvailableItemsViewKind);
begin
if FCustomizeAvailableItemsViewKind <> Value then
begin
FCustomizeAvailableItemsViewKind := Value;
CustomizeFormUpdate([cfutContent, cfutSelection]);
end;
end;
procedure TdxCustomLayoutControl.SetCustomizeFormTabbedView(Value: Boolean);
begin
if FCustomizeFormTabbedView <> Value then
begin
FCustomizeFormTabbedView := Value;
CustomizeFormUpdate([cfutContent, cfutSelection]);
end;
end;
procedure TdxCustomLayoutControl.SetShowDesignSelectors(Value: Boolean);
begin
if FShowDesignSelectors <> Value then
begin
FShowDesignSelectors := Value;
InvalidateWithChildren;
CustomizeFormUpdate([cfutContent, cfutSelection]);
end;
end;
procedure TdxCustomLayoutControl.SetHighlightRoot(Value: Boolean);
begin
if FHighlightRoot <> Value then
begin
FHighlightRoot := Value;
LayoutChanged(False);
end;
end;
procedure TdxCustomLayoutControl.SetIsPlaceControlsNeeded(Value: Boolean);
begin
if FIsPlaceControlsNeeded <> Value then
begin
FIsPlaceControlsNeeded := Value;
if Value then
PlaceControls(nil);
end;
end;
procedure TdxCustomLayoutControl.SetRootGroup(Value: TdxLayoutGroup);
begin
ItemWithMouse := nil;
DestroyHandlers;
if Value <> nil then
begin
if FRootGroup <> nil then
begin
Value.FAlignHorz := FRootGroup.AlignHorz;
Value.FAlignVert := FRootGroup.AlignVert;
end
else
begin
Value.FAlignHorz := ahLeft;
Value.FAlignVert := avTop;
end;
end;
if IsDestroying or ((FRootGroup <> nil) and not FRootGroup.IsDestroying) then
FRootGroup.Free;
FRootGroup := Value;
if Value = nil then Exit;
FRootGroup.Container := Self;
CreateHandlers;
FRootGroup.Hidden := True;
end;
procedure TdxCustomLayoutControl.SetItemWithMouse(Value: TdxCustomLayoutItem);
begin
if FItemWithMouse <> Value then
begin
if FItemWithMouse <> nil then
FItemWithMouse.MouseLeave;
FItemWithMouse := Value;
if FItemWithMouse <> nil then
FItemWithMouse.MouseEnter;
end;
end;
procedure TdxCustomLayoutControl.SetLayoutDirection(Value: TdxLayoutDirection);
begin
FRootGroup.LayoutDirection := Value;
end;
procedure TdxCustomLayoutControl.SetLeftPos(Value: Integer);
var
APrevLeftPos: Integer;
begin
CheckLeftPos(Value);
if FLeftPos <> Value then
begin
Update;
APrevLeftPos := FLeftPos;
FLeftPos := Value;
LayoutChanged;
ScrollContent(APrevLeftPos, FLeftPos, True);
end;
end;
procedure TdxCustomLayoutControl.SetLayoutLookAndFeel(Value: TdxCustomLayoutLookAndFeel);
begin
if FLayoutLookAndFeel <> Value then
begin
GetLayoutLookAndFeel.RemoveUser(Self);
FLayoutLookAndFeel := Value;
GetLayoutLookAndFeel.AddUser(Self);
LayoutLookAndFeelUserChanged;
end;
end;
procedure TdxCustomLayoutControl.SetShowHiddenGroupsBounds(Value: Boolean);
begin
if FShowHiddenGroupsBounds <> Value then
begin
FShowHiddenGroupsBounds := Value;
LayoutChanged;
end;
end;
procedure TdxCustomLayoutControl.SetTopPos(Value: Integer);
var
APrevTopPos: Integer;
begin
CheckTopPos(Value);
if FTopPos <> Value then
begin
Update;
APrevTopPos := FTopPos;
FTopPos := Value;
LayoutChanged;
ScrollContent(APrevTopPos, FTopPos, False);
end;
end;
function TdxCustomLayoutControl.GetIniFileName: string;
begin
Result := OptionsStoring.IniFileName;
end;
function TdxCustomLayoutControl.GetRegistryPath: string;
begin
Result := OptionsStoring.RegistryPath;
end;
function TdxCustomLayoutControl.GetStoreInIniFile: Boolean;
begin
Result := OptionsStoring.StoreToIniFile;
end;
function TdxCustomLayoutControl.GetStoreInRegistry: Boolean;
begin
Result := OptionsStoring.StoreToRegistry;
end;
procedure TdxCustomLayoutControl.SetIniFileName(const Value: string);
begin
OptionsStoring.IniFileName := Value;
end;
procedure TdxCustomLayoutControl.SetRegistryPath(const Value: string);
begin
OptionsStoring.RegistryPath := Value;
end;
procedure TdxCustomLayoutControl.SetStoreInIniFile(const Value: Boolean);
begin
OptionsStoring.StoreToIniFile := Value;
end;
procedure TdxCustomLayoutControl.SetStoreInRegistry(const Value: Boolean);
begin
OptionsStoring.StoreToRegistry := Value;
end;
procedure TdxCustomLayoutControl.SetOptionsStoring(Value: TdxStoringOptions);
begin
FOptionsStoring.Assign(Value);
end;
procedure TdxCustomLayoutControl.CreateHandlers;
begin
FPainter := GetPainterClass.Create(Self);
FViewInfo := GetViewInfoClass.Create(Self);
end;
procedure TdxCustomLayoutControl.DestroyHandlers;
begin
FreeAndNil(FViewInfo);
FreeAndNil(FPainter);
end;
procedure TdxCustomLayoutControl.CreateConstraints;
begin
FAlignmentConstraints := TList.Create;
end;
procedure TdxCustomLayoutControl.DestroyConstraints;
var
I: Integer;
begin
for I := AlignmentConstraintCount - 1 downto 0 do
AlignmentConstraints[I].Free;
FreeAndNil(FAlignmentConstraints);
end;
procedure TdxCustomLayoutControl.AddAlignmentConstraint(AConstraint: TdxLayoutAlignmentConstraint);
begin
FAlignmentConstraints.Add(AConstraint);
AConstraint.FControl := Self;
SetComponentName(AConstraint, Name + 'AlignmentConstraint', IsDesigning, IsLoading);
end;
procedure TdxCustomLayoutControl.RemoveAlignmentConstraint(AConstraint: TdxLayoutAlignmentConstraint);
begin
FAlignmentConstraints.Remove(AConstraint);
AConstraint.FControl := nil;
end;
procedure TdxCustomLayoutControl.RefreshBoldFont;
begin
FBoldFont.Assign(Font);
with FBoldFont do
Style := Style + [fsBold];
dxLayoutTextMetrics.Unregister(FBoldFont);
end;
procedure TdxCustomLayoutControl.InitializeSubControlsCxLookAndFeel;
begin
GetLayoutLookAndFeel.InitializeSubControlCxLookAndFeel(HScrollBar.LookAndFeel);
GetLayoutLookAndFeel.InitializeSubControlCxLookAndFeel(VScrollBar.LookAndFeel);
GetLayoutLookAndFeel.InitializeSubControlCxLookAndFeel(SizeGrip.LookAndFeel);
end;
procedure TdxCustomLayoutControl.PlaceControls(AItemViewInfo: TdxCustomLayoutItemViewInfo);
begin
if AItemViewInfo <> nil then
begin
IsPlaceControlsNeeded := False;
Painter.PlaceControls(AItemViewInfo);
end
else
if TdxCustomLayoutLookAndFeelAccess(GetLayoutLookAndFeel).ForceControlArrangement then
SendMessage(Handle, DXM_PLACECONTROLS, 0, 0)
else
PostMessage(Handle, DXM_PLACECONTROLS, 0, 0);
end;
procedure TdxCustomLayoutControl.AddAbsoluteItem(AItem: TdxCustomLayoutItem);
begin
FAbsoluteItems.Add(AItem);
end;
procedure TdxCustomLayoutControl.ExtractAbsoluteItem(AItem: TdxCustomLayoutItem);
begin
FAbsoluteItems.Extract(AItem);
end;
procedure TdxCustomLayoutControl.AddAvailableItem(AItem: TdxCustomLayoutItem);
begin
FAvailableItems.Add(AItem);
AItem.Container := Self;
end;
procedure TdxCustomLayoutControl.ExtractAvailableItem(AItem: TdxCustomLayoutItem);
begin
FAvailableItems.Extract(AItem);
end;
procedure TdxCustomLayoutControl.WMNCDestroy(var Message: TWMNCDestroy);
begin
IsPlaceControlsNeeded := False;
inherited;
end;
{$IFNDEF DELPHI7}
procedure TdxCustomLayoutControl.WMPrintClient(var Message: TWMPrintClient);
begin
with Message do
if Result <> 1 then
if ((Flags and PRF_CHECKVISIBLE) = 0) or Visible then
PaintHandler(TWMPaint(Message))
else
inherited
else
inherited;
end;
{$ENDIF}
procedure TdxCustomLayoutControl.CMControlChange(var Message: TCMControlChange);
var
AControl: TControl;
P: TPoint;
AGroup: TdxLayoutGroup;
AIndex: Integer;
begin
inherited;
if not (IsLoading or IsDestroying) then
begin
AControl := Message.Control;
if Message.Inserting then
begin
if (csAncestor in AControl.ComponentState) or
IsInternalControl(AControl) or (FindItem(AControl) <> nil) then
Exit;
P := AControl.BoundsRect.TopLeft;
AGroup := ViewInfo.GetHitTest(P).GetGroupForInsert;
if AGroup = nil then
AGroup := Items;
CustomizeFormBeginUpdate;
try
AIndex := AGroup.ViewInfo.GetInsertionPos(P);
AGroup.CreateItemForControl(AControl).VisibleIndex := AIndex;
finally
CustomizeFormEndUpdate;
end;
end
// #DG else
// #DG FindItem(AControl).Free;
end;
end;
procedure TdxCustomLayoutControl.CMDialogChar(var Message: TCMDialogChar);
begin
if FRootGroup.ProcessDialogChar(Message.CharCode) then
Message.Result := 1
else
inherited;
end;
{
procedure TdxCustomLayoutControl.CMFreeItem(var Message: TMessage);
begin
TObject(Message.WParam).Free;
end;
}
procedure TdxCustomLayoutControl.DXMPlaceControls(var Message: TMessage);
begin
IsPlaceControlsNeeded := False;
Painter.PlaceControls(ViewInfo.ItemsViewInfo);
end;
procedure TdxCustomLayoutControl.DXMBuildSelectionLayer(var Message: TMessage);
begin
if not IsUpdateLocked and (ViewInfo <> nil) then
ViewInfo.BuildSelectionLayer;
end;
function TdxCustomLayoutControl.CanAutoSize(var NewWidth, NewHeight: Integer): Boolean;
begin
if IsDesigning then
Result := False
else
begin
Result := True;
if (ViewInfo.ItemsViewInfo.AlignHorz <> ahClient) and (Align in [alNone, alLeft, alRight]) then
NewWidth := cxRectWidth(ContentBounds);
if (ViewInfo.ItemsViewInfo.AlignVert <> avClient) and (Align in [alNone, alTop, alBottom]) then
NewHeight := cxRectHeight(ContentBounds);
end;
end;
procedure TdxCustomLayoutControl.AlignControls(AControl: TControl; var Rect: TRect);
begin
end;
function TdxCustomLayoutControl.AllowAutoDragAndDropAtDesignTime(X, Y: Integer;
Shift: TShiftState): Boolean;
begin
Result := not GetDesignHitTest(X, Y, Shift);
end;
function TdxCustomLayoutControl.AllowDragAndDropWithoutFocus: Boolean;
begin
Result := FCustomization;
end;
procedure TdxCustomLayoutControl.BoundsChanged;
begin
LayoutChanged;
inherited;
end;
function TdxCustomLayoutControl.CanDrag(X, Y: Integer): Boolean;
begin
Result := inherited CanDrag(X, Y) and not IsDesigning;
end;
function TdxCustomLayoutControl.CanFocusOnClick(X, Y: Integer): Boolean;
begin
Result := inherited CanFocusOnClick(X, Y) and not IsCustomization;
if ItemWithMouse <> nil then
Result := Result and not ItemWithMouse.CanFocusOnClick(X, Y);
end;
procedure TdxCustomLayoutControl.CreateParams(var Params: TCreateParams);
begin
inherited;
with Params do
WindowClass.style := WindowClass.style and not (CS_HREDRAW or CS_VREDRAW);
end;
procedure TdxCustomLayoutControl.DblClick;
begin
inherited;
if IsDesigning then
Customization := True;
end;
procedure TdxCustomLayoutControl.FontChanged;
begin
inherited;
dxLayoutTextMetrics.Unregister(Font);
RefreshBoldFont;
LayoutLookAndFeelUserChanged;
end;
procedure TdxCustomLayoutControl.GetChildren(Proc: TGetChildProc; Root: TComponent);
var
I: Integer;
begin
inherited;
if Owner = Root then
begin
Proc(FRootGroup);
for I := 0 to AvailableItemCount - 1 do
Proc(AvailableItems[I]);
for I := 0 to AlignmentConstraintCount - 1 do
Proc(AlignmentConstraints[I]);
end;
end;
function TdxCustomLayoutControl.GetCursor(X, Y: Integer): TCursor;
var
AHitTest: TdxCustomLayoutHitTest;
begin
AHitTest := ViewInfo.GetHitTest(X, Y);
if AHitTest is TdxCustomLayoutItemHitTest then
Result := TdxCustomLayoutItemHitTest(AHitTest).Item.GetCursor(X, Y)
else
Result := crDefault;
if Result = crDefault then
Result := inherited GetCursor(X, Y);
end;
function TdxCustomLayoutControl.GetDesignHitTest(X, Y: Integer; Shift: TShiftState): Boolean;
function IsGrabHandle(AHandle: THandle): Boolean;
const
GrabHandleClassName = 'TGrabHandle';
begin
Result := cxGetClassName(AHandle) = GrabHandleClassName;
end;
var
AHitTest: TdxCustomLayoutHitTest;
begin
Result := inherited GetDesignHitTest(X, Y, Shift);
if not Result then
begin
AHitTest := ViewInfo.GetHitTest(X, Y);
Result := not (ssRight in Shift) and not FRightButtonPressed and
(AHitTest is TdxCustomLayoutItemHitTest) and
not IsToolSelected and not IsGrabHandle(cxWindowFromPoint(ClientToScreen(Point(X, Y))));
end;
FRightButtonPressed := ssRight in Shift;
end;
function TdxCustomLayoutControl.HasBackground: Boolean;
begin
Result := {$IFDEF DELPHI7}ThemeServices.ThemesEnabled and ParentBackground{$ELSE}inherited HasBackground{$ENDIF};
end;
function TdxCustomLayoutControl.IsInternalControl(AControl: TControl): Boolean;
begin
Result := inherited IsInternalControl(AControl) or (AControl is TdxLayoutTabbedGroupTabControl);
end;
procedure TdxCustomLayoutControl.Loaded;
begin
inherited;
if not IsDesigning then
Restore;
LayoutChanged;
end;
procedure TdxCustomLayoutControl.MouseDown(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
begin
AssignItemWithMouse(X, Y);
inherited;
if ItemWithMouse <> nil then
ItemWithMouse.MouseDown(Button, Shift, X, Y);
end;
procedure TdxCustomLayoutControl.MouseLeave(AControl: TControl);
begin
inherited;
ItemWithMouse := nil;
end;
procedure TdxCustomLayoutControl.MouseMove(Shift: TShiftState; X, Y: Integer);
begin
AssignItemWithMouse(X, Y);
if ItemWithMouse <> nil then
ItemWithMouse.MouseMove(Shift, X, Y);
inherited;
end;
procedure TdxCustomLayoutControl.MouseUp(Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
inherited;
AssignItemWithMouse(X, Y);
if ItemWithMouse <> nil then
ItemWithMouse.MouseUp(Button, Shift, X, Y);
end;
procedure TdxCustomLayoutControl.Paint;
begin
if not IsUpdateLocked then
begin
inherited;
Painter.Paint;
end;
end;
procedure TdxCustomLayoutControl.SetName(const Value: TComponentName);
function GetItem(ACaller: TComponent; Index: Integer): TComponent;
begin
if Index = 0 then
Result := TdxCustomLayoutControl(ACaller).Items
else
Result := TdxCustomLayoutControl(ACaller).AbsoluteItems[Index - 1];
end;
function GetAlignmentConstraint(ACaller: TComponent; Index: Integer): TComponent;
begin
Result := TdxCustomLayoutControl(ACaller).AlignmentConstraints[Index];
end;
var
AOldName: string;
begin
AOldName := Name;
inherited;
RenameComponents(Self, Owner, Name, AOldName, 1 + AbsoluteItemCount, @GetItem);
RenameComponents(Self, Owner, Name, AOldName, AlignmentConstraintCount, @GetAlignmentConstraint);
CustomizeFormUpdate([cfutCaption, cfutContent]);
end;
{$IFDEF DELPHI7}
procedure TdxCustomLayoutControl.SetParentBackground(Value: Boolean);
begin
if Value then
ControlStyle := ControlStyle - [csOpaque]
else
ControlStyle := ControlStyle + [csOpaque];
inherited;
end;
{$ENDIF}
procedure TdxCustomLayoutControl.WriteState(Writer: TWriter);
begin
if HandleAllocated then
SendMessage(Handle, WM_SETREDRAW, 0, 0);
try
Items.RestoreItemControlSize;
inherited;
finally
if HandleAllocated then
SendMessage(Handle, WM_SETREDRAW, 1, 0);
LayoutChanged;
end;
end;
procedure TdxCustomLayoutControl.WndProc(var Message: TMessage);
var
AControl: TControl;
P: TPoint;
AHitTest: TdxCustomLayoutHitTest;
begin
if (IsDesigning or Customization) and HandleAllocated then
case Message.Msg of
WM_LBUTTONDOWN:
if GetCapture <> Handle then
begin
P := SmallPointToPoint(TWMMouse(Message).Pos);
AControl := ControlAtPos(P, True);
if (AControl <> nil) and not (AControl is TWinControl) then
begin
AHitTest := ViewInfo.GetHitTest(P);
if Customization or ((AHitTest <> nil) and (AHitTest is TdxLayoutItemHitTest) and (AHitTest as TdxLayoutItemHitTest).Item.ViewInfo.PtInDesignSelectorRect(P)) then
SetCaptureControl(Self);
end;
end;
end;
inherited WndProc(Message);
end;
procedure TdxCustomLayoutControl.InitScrollBarsParameters;
begin
inherited;
SetScrollBarInfo(sbHorizontal, 0, ViewInfo.ContentWidth - 1,
ScrollStep, ViewInfo.ClientWidth, LeftPos, True, True);
SetScrollBarInfo(sbVertical, 0, ViewInfo.ContentHeight - 1,
ScrollStep, ViewInfo.ClientHeight, TopPos, True, True);
end;
function TdxCustomLayoutControl.NeedsToBringInternalControlsToFront: Boolean;
begin
Result := True;
end;
procedure TdxCustomLayoutControl.Scroll(AScrollBarKind: TScrollBarKind;
AScrollCode: TScrollCode; var AScrollPos: Integer);
function GetContentPos: Integer;
begin
if AScrollBarKind = sbHorizontal then
Result := LeftPos
else
Result := TopPos;
end;
procedure SetContentPos(Value: Integer);
begin
if AScrollBarKind = sbHorizontal then
LeftPos := Value
else
TopPos := Value;
end;
function GetPageScrollStep: Integer;
begin
if AScrollBarKind = sbHorizontal then
Result := ClientWidth
else
Result := ClientHeight;
end;
begin
inherited;
case AScrollCode of
scLineUp:
SetContentPos(GetContentPos - ScrollStep);
scLineDown:
SetContentPos(GetContentPos + ScrollStep);
scPageUp:
SetContentPos(GetContentPos - GetPageScrollStep);
scPageDown:
SetContentPos(GetContentPos + GetPageScrollStep);
scTrack:
SetContentPos(AScrollPos);
end;
AScrollPos := GetContentPos;
end;
function TdxCustomLayoutControl.CanDragAndDrop: Boolean;
begin
Result := not IsDesigning or not (csInline in Owner.ComponentState);
end;
function TdxCustomLayoutControl.GetDragAndDropObjectClass: TcxDragAndDropObjectClass;
begin
Result := TdxLayoutControlDragAndDropObject;
end;
function TdxCustomLayoutControl.StartDragAndDrop(const P: TPoint): Boolean;
var
AHitTest: TdxCustomLayoutHitTest;
AItem: TdxCustomLayoutItem;
begin
Result := False;
if IsCustomization and CanDragAndDrop then
begin
AHitTest := ViewInfo.GetHitTest(P);
if AHitTest is TdxCustomLayoutItemHitTest then
begin
AItem := TdxCustomLayoutItemHitTest(AHitTest).Item;
if not AItem.IsRoot then
begin
(DragAndDropObject as TdxLayoutControlDragAndDropObject).Init(dsControl, AItem);
Result := True;
end
end;
end;
end;
function TdxCustomLayoutControl.GetLayoutLookAndFeel: TdxCustomLayoutLookAndFeel;
begin
Result := FLayoutLookAndFeel;
if Result = nil then
Result := dxLayoutDefaultLookAndFeel;
end;
function TdxCustomLayoutControl.GetCxLookAndFeel: TcxLookAndFeel;
begin
Result := inherited LookAndFeel;
end;
procedure TdxCustomLayoutControl.BeginLayoutLookAndFeelUserDestroying;
begin
BeginUpdate;
end;
procedure TdxCustomLayoutControl.EndLayoutLookAndFeelUserDestroying;
begin
EndUpdate;
end;
procedure TdxCustomLayoutControl.LayoutLookAndFeelUserChanged;
begin
if (LayoutLookAndFeel <> nil) and not DoubleBuffered then
DoubleBuffered := LayoutLookAndFeel.NeedDoubleBuffered;
if (FRootGroup <> nil) and (GetLayoutLookAndFeel <> nil) then
FRootGroup.LayoutLookAndFeelUserChanged;
InitializeSubControlsCxLookAndFeel;
end;
procedure TdxCustomLayoutControl.LayoutLookAndFeelUserDestroyed;
begin
LayoutLookAndFeel := nil;
end;
procedure TdxCustomLayoutControl.SelectionChanged;
begin
Items.SelectionChanged;
end;
function TdxCustomLayoutControl.GetPainterClass: TdxLayoutControlPainterClass;
begin
Result := TdxLayoutControlPainter;
end;
function TdxCustomLayoutControl.GetViewInfoClass: TdxLayoutControlViewInfoClass;
begin
Result := TdxLayoutControlViewInfo;
end;
procedure TdxCustomLayoutControl.AssignItemWithMouse(X, Y: Integer);
begin
ItemWithMouse := ViewInfo.GetItemWithMouse(Point(X, Y));
end;
procedure TdxCustomLayoutControl.AvailableItemListChanged(Sender: TObject; AComponent: TComponent; AAction: TcxComponentCollectionNotification);
begin
CustomizeFormUpdate([cfutContent, cfutSelection]);
end;
procedure TdxCustomLayoutControl.UpdateCustomizationControls;
var
I: Integer;
AItem: TdxLayoutItem;
begin
FCustomizationControls.Clear;
for I := 0 to AbsoluteItemCount - 1 do
begin
if AbsoluteItems[I] is TdxLayoutItem then
begin
AItem := TdxLayoutItem(AbsoluteItems[I]);
if AItem.HasWinControl then
TdxSatelliteControls(FCustomizationControls).AddControl(TWinControl(AItem.Control), TdxCustomizationControlItem);
end;
end;
end;
function TdxCustomLayoutControl.CalculateCustomizeFormBounds(const AFormBounds: TRect): TRect;
var
AControlBounds, ADesktopBounds: TRect;
begin
AControlBounds := BoundsRect;
MapWindowPoints(Parent.Handle, 0, AControlBounds, 2);
ADesktopBounds := GetDesktopWorkArea(AControlBounds.TopLeft);
Result := AFormBounds;
with AControlBounds do
begin
if (ADesktopBounds.Right - Right >= Result.Right - Result.Left) or
(ADesktopBounds.Right - Right >= Left - ADesktopBounds.Left) then
OffsetRect(Result, Right - Result.Left, 0)
else
OffsetRect(Result, Left - Result.Right, 0);
OffsetRect(Result, 0,
(Top + Bottom - (Result.Bottom - Result.Top)) div 2 - Result.Top);
end;
with ADesktopBounds do
begin
if Result.Left < Left then
OffsetRect(Result, Left - Result.Left, 0);
if Result.Right > Right then
OffsetRect(Result, Right - Result.Right, 0);
if Result.Top < Top then
OffsetRect(Result, 0, Top - Result.Top);
end;
end;
function TdxCustomLayoutControl.CanMultiSelect: Boolean;
begin
Result := True;
end;
function TdxCustomLayoutControl.CanShowSelection: Boolean;
begin
Result := {$IFDEF DELPHI6}True{$ELSE}CanMultiSelect{$ENDIF};
end;
procedure TdxCustomLayoutControl.PostBuildSelectionLayer;
begin
if HandleAllocated then
PostMessage(Handle, DXM_BUILDSELECTIONLAYER, 0, 0);
end;
procedure TdxCustomLayoutControl.CheckLeftPos(var Value: Integer);
begin
Value := Max(Min(Value, ViewInfo.ContentWidth - ViewInfo.ClientWidth), 0);
end;
procedure TdxCustomLayoutControl.CheckPositions;
begin
LeftPos := LeftPos;
TopPos := TopPos;
end;
procedure TdxCustomLayoutControl.CheckTopPos(var Value: Integer);
begin
Value := Max(Min(Value, ViewInfo.ContentHeight - ViewInfo.ClientHeight), 0);
end;
procedure TdxCustomLayoutControl.CustomizeFormBeginUpdate;
begin
Inc(FCustomizeFormUpdateLockCount);
end;
procedure TdxCustomLayoutControl.CustomizeFormCancelUpdate;
begin
Dec(FCustomizeFormUpdateLockCount);
end;
procedure TdxCustomLayoutControl.CustomizeFormEndUpdate;
begin
Dec(FCustomizeFormUpdateLockCount);
CustomizeFormUpdate([cfutCaption, cfutContent, cfutSelection]);
end;
procedure TdxCustomLayoutControl.CustomizeFormUpdate(
AUpdateTypes: TdxLayoutCustomizeFormUpdateTypes);
begin
if not Customization or IsUpdateLocked or (FCustomizeFormUpdateLockCount <> 0) or
(csDestroying in FCustomizeForm.ComponentState) then
Exit;
if cfutCaption in AUpdateTypes then
TdxLayoutControlCustomizeForm(CustomizeForm).UpdateCaption;
if cfutContent in AUpdateTypes then
TdxLayoutControlCustomizeForm(CustomizeForm).UpdateContent;
if cfutSelection in AUpdateTypes then
TdxLayoutControlCustomizeForm(CustomizeForm).UpdateSelection;
end;
procedure TdxCustomLayoutControl.DoCustomization;
begin
CallNotify(FOnCustomization, Self);
end;
procedure TdxCustomLayoutControl.DragAndDropBegan;
begin
// todo: remove
end;
function TdxCustomLayoutControl.GetAlignmentConstraintClass: TdxLayoutAlignmentConstraintClass;
begin
Result := TdxLayoutAlignmentConstraint;
end;
function TdxCustomLayoutControl.GetDefaultGroupClass: TdxLayoutGroupClass;
begin
Result := TdxLayoutGroup;
end;
function TdxCustomLayoutControl.GetDefaultItemClass: TdxLayoutItemClass;
begin
Result := TdxLayoutItem;
end;
function TdxCustomLayoutControl.GetDesignSelectorRect: TRect;
const
Offset = 3;
Width = 16;
begin
with ClientBounds do
Result := Rect(Right - Width - Offset, Bottom - Width - Offset, Right - Offset, Bottom - Offset);
end;
function TdxCustomLayoutControl.IsCustomization: Boolean;
begin
Result := Customization or IsDesigning;
end;
function TdxCustomLayoutControl.IsToolSelected: Boolean;
begin
Result := IsDesigning and (dxLayoutDesignTimeHelper <> nil) and
dxLayoutDesignTimeHelper.IsToolSelected;
end;
function TdxCustomLayoutControl.IsUpdateLocked: Boolean;
begin
Result := FUpdateLockCount <> 0;
end;
procedure TdxCustomLayoutControl.LayoutChanged(ANeedPack: Boolean = True);
procedure BeforeCalculateViewInfo;
var
I: Integer;
begin
Items.BeforeCalculateViewInfo;
for I := 0 to AvailableItemCount - 1 do
AvailableItems[I].BeforeCalculateViewInfo;
end;
procedure AfterCalculateViewInfo;
var
I: Integer;
begin
Items.AfterCalculateViewInfo;
for I := 0 to AvailableItemCount - 1 do
AvailableItems[I].AfterCalculateViewInfo;
end;
begin
if not IsDestroying and not IsLoading and not IsUpdateLocked then
begin
BeginUpdate;
try
if ANeedPack then
Items.Pack;
BeforeCalculateViewInfo;
ViewInfo.Calculate;
AfterCalculateViewInfo;
finally
CancelUpdate;
end;
CustomizeFormUpdate([cfutContent, cfutSelection]);
AdjustSize;
{$IFDEF DELPHI12}
TControlAccess(Parent).AdjustSize; // bug in D12
{$ENDIF}
UpdateScrollBars;
Invalidate;
PostBuildSelectionLayer;
end;
end;
procedure TdxCustomLayoutControl.CreateRootGroup;
begin
SetRootGroup(GetDefaultGroupClass.Create(Owner{nil}));
end;
{procedure TdxCustomLayoutControl.PostFree(AObject: TObject);
begin
if HandleAllocated then
PostMessage(Handle, CM_FREEITEM, WParam(AObject), 0);
end;}
procedure TdxCustomLayoutControl.ScrollContent(APrevPos, ACurPos: Integer;
AHorzScrolling: Boolean);
var
ADelta: Integer;
AScrollBounds: TRect;
begin
if not HandleAllocated then Exit;
ADelta := -(ACurPos - APrevPos);
AScrollBounds := ViewInfo.ClientBounds;
//ValidateRect(Handle, @AScrollBounds);
ScrollWindowEx(Handle, Ord(AHorzScrolling) * ADelta, Ord(not AHorzScrolling) * ADelta,
@AScrollBounds, nil, 0, nil, SW_INVALIDATE or SW_ERASE{ or SW_SCROLLCHILDREN bug in WinAPI});
UpdateWindow(Handle);
end;
type
PdxLayoutItemPosition = ^TdxLayoutItemPosition;
TdxLayoutItemPosition = record
Item: TdxCustomLayoutItem;
ParentName: string;
Index: Integer;
end;
function ComparePositions(Item1, Item2: Pointer): Integer;
begin
Result := PdxLayoutItemPosition(Item1).Index - PdxLayoutItemPosition(Item2).Index;
end;
procedure TdxCustomLayoutControl.LoadFromCustomIniFile(AIniFile: TCustomIniFile;
const ARootSection: string);
var
AItems: TList;
APositions: TList;
AItemCount, I: Integer;
function CreateItemsList: TList;
begin
Result := TList.Create;
Result.Count := AbsoluteItemCount;
Move(FAbsoluteItems.List^, Result.List^, Result.Count * SizeOf(Pointer));
end;
procedure PrepareItems;
var
I: Integer;
begin
for I := 0 to AbsoluteItemCount - 1 do
AbsoluteItems[I].Parent := nil;
end;
function GetItemSection(AIndex: Integer): string;
begin
Result := 'Item' + IntToStr(AIndex);
if ARootSection <> '' then
Result := ARootSection + '\' + Result;
end;
procedure AddPosition(AItem: TdxCustomLayoutItem; const AParentName: string;
AIndex: Integer);
var
APosition: PdxLayoutItemPosition;
begin
New(APosition);
with APosition^ do
begin
Item := AItem;
ParentName := AParentName;
Index := AIndex;
end;
APositions.Add(APosition);
end;
procedure LoadItem(const ASection: string);
var
AName, AParentName: string;
AItem: TdxCustomLayoutItem;
AIndex: Integer;
AGroup: TdxLayoutGroup;
begin
AName := AIniFile.ReadString(ASection, 'Name', '');
if AName = '' then Exit;
AItem := FindItem(AName);
AItems.Remove(AItem);
if AItem = nil then
begin
AItem := CreateGroup;
AItem.Name := AName;
end;
AParentName := AIniFile.ReadString(ASection, 'ParentName', '');
AIndex := AIniFile.ReadInteger(ASection, 'Index', -1);
AddPosition(AItem, AParentName, AIndex);
if AItem is TdxLayoutGroup then
begin
AGroup := TdxLayoutGroup(AItem);
AGroup.Hidden := AIniFile.ReadBool(ASection, 'Hidden', False);
AGroup.LayoutDirection :=
TdxLayoutDirection(AIniFile.ReadInteger(ASection, 'LayoutDirection', 0));
if AGroup.IsUserDefined and not AGroup.Hidden then
AGroup.Caption := AIniFile.ReadString(ASection, 'Caption', '');
end;
end;
procedure DestroyNonLoadedItems;
var
I: Integer;
function CanDestroy(AItem: TdxCustomLayoutItem): Boolean;
function ItemExists(AItem: Pointer): Boolean;
var
I: Integer;
begin
for I := 0 to AbsoluteItemCount - 1 do
begin
Result := AbsoluteItems[I] = AItem;
if Result then Exit;
end;
Result := False;
end;
begin
Result := ItemExists(AItem) and
(AItem is TdxLayoutGroup) and TdxLayoutGroup(AItem).CanDestroy;
end;
begin
for I := 0 to AItems.Count - 1 do
if CanDestroy(AItems[I]) then
TObject(AItems[I]).Free;
end;
procedure UpdatePositions;
var
I: Integer;
APosition: PdxLayoutItemPosition;
begin
APositions.Sort(ComparePositions);
for I := 0 to APositions.Count - 1 do
begin
APosition := PdxLayoutItemPosition(APositions[I]);
with APosition^ do
begin
Item.Parent := FindItem(ParentName) as TdxLayoutGroup;
Item.Index := Index;
end;
end;
end;
begin
AItems := CreateItemsList;
APositions := TList.Create;
try
AItemCount := AIniFile.ReadInteger(ARootSection, 'ItemCount', -1);
if AItemCount = -1 then Exit;
BeginUpdate;
try
PrepareItems;
for I := 0 to AItemCount - 1 do
LoadItem(GetItemSection(I));
DestroyNonLoadedItems;
UpdatePositions;
finally
EndUpdate;
end;
finally
for I := 0 to APositions.Count - 1 do
Dispose(PdxLayoutItemPosition(APositions[I]));
APositions.Free;
AItems.Free;
end;
end;
function CompareItemsByIsUserDefined(Item1, Item2: Pointer): Integer;
var
AItem1, AItem2: TdxCustomLayoutItem;
begin
AItem1 := TdxCustomLayoutItem(Item1);
AItem2 := TdxCustomLayoutItem(Item2);
if (AItem1 is TdxLayoutGroup) and (AItem2 is TdxLayoutGroup) then
Result :=
Ord(TdxLayoutGroup(AItem2).IsUserDefined) - Ord(TdxLayoutGroup(AItem1).IsUserDefined)
else
Result := Ord(AItem2 is TdxLayoutGroup) - Ord(AItem1 is TdxLayoutGroup);
if Result = 0 then
Result := Integer(Item1) - Integer(Item2);
end;
procedure TdxCustomLayoutControl.SaveToCustomIniFile(AIniFile: TCustomIniFile;
const ARootSection: string);
var
AItems: TList;
I: Integer;
function CreateItemsList: TList;
begin
Result := TList.Create;
Result.Count := AbsoluteItemCount;
Move(FAbsoluteItems.List^, Result.List^, Result.Count * SizeOf(Pointer));
Result.Sort(CompareItemsByIsUserDefined);
Result.Insert(0, Items);
end;
function GetItemSection(AIndex: Integer): string;
begin
Result := 'Item' + IntToStr(AIndex);
if ARootSection <> '' then
Result := ARootSection + '\' + Result;
end;
procedure DeletePrevSettings;
var
ABaseSectionName: string;
ASections: TStringList;
I: Integer;
begin
ABaseSectionName := ARootSection;
if ABaseSectionName <> '' then
ABaseSectionName := ABaseSectionName + '\';
ASections := TStringList.Create;
try
AIniFile.ReadSections(ASections);
for I := 0 to ASections.Count - 1 do
if Copy(ASections[I], 1, Length(ABaseSectionName)) = ABaseSectionName then
AIniFile.EraseSection(ASections[I]);
finally
ASections.Free;
end;
end;
procedure SaveItem(const ASection: string; AItem: TdxCustomLayoutItem);
var
AGroup: TdxLayoutGroup;
function GetParentName: string;
begin
if AItem.Parent <> nil then
Result := AItem.Parent.Name
else
Result := '';
end;
begin
AIniFile.WriteString(ASection, 'Name', AItem.Name);
AIniFile.WriteString(ASection, 'ParentName', GetParentName);
AIniFile.WriteInteger(ASection, 'Index', AItem.Index);
if AItem is TdxLayoutGroup then
begin
AGroup := TdxLayoutGroup(AItem);
AIniFile.WriteBool(ASection, 'Hidden', AGroup.Hidden);
AIniFile.WriteInteger(ASection, 'LayoutDirection', Integer(AGroup.LayoutDirection));
if AGroup.IsUserDefined and not AGroup.Hidden then
AIniFile.WriteString(ASection, 'Caption', AItem.Caption);
end;
end;
begin
DeletePrevSettings;
AItems := CreateItemsList;
try
AIniFile.WriteInteger(ARootSection, 'ItemCount', AItems.Count);
for I := 0 to AItems.Count - 1 do
SaveItem(GetItemSection(I), AItems[I]);
finally
AItems.Free;
end;
end;
function TdxCustomLayoutControl.CanDeleteComponent(AComponent: TComponent): Boolean;
begin
Result := (FSelectionHelper <> nil) and
FSelectionHelper.CanDeleteComponent(AComponent);
end;
procedure TdxCustomLayoutControl.ClearSelection;
begin
if (FSelectionHelper <> nil) then
FSelectionHelper.ClearSelection;
end;
procedure TdxCustomLayoutControl.GetSelection(AList: TList);
begin
if (FSelectionHelper <> nil) then
FSelectionHelper.GetSelection(AList);
end;
function TdxCustomLayoutControl.IsComponentSelected(AComponent: TPersistent): Boolean;
begin
Result := (FSelectionHelper <> nil) and FSelectionHelper.IsComponentSelected(AComponent);
end;
procedure TdxCustomLayoutControl.SelectComponent(AComponent: TPersistent;
AShift: TShiftState = []);
begin
if FSelectionHelper <> nil then
FSelectionHelper.SelectComponent(AComponent, AShift);
end;
procedure TdxCustomLayoutControl.SetSelection(AList: TList);
begin
if FSelectionHelper <> nil then
FSelectionHelper.SetSelection(AList);
end;
function TdxCustomLayoutControl.UniqueName(const BaseName: string): string;
begin
if FSelectionHelper <> nil then
Result := FSelectionHelper.UniqueName(BaseName);
end;
//IdxLayoutSelectionChanged
procedure TdxCustomLayoutControl.LayoutSelectionChanged(ASelection: TList; AAction: TdxLayoutSelectionAction);
begin
if not IsDestroying and (AAction in [lsaAdded, lsaChanged]) and not IsUpdateLocked then
begin
CustomizeFormUpdate([cfutSelection]);
if IsDesigning then
InvalidateRect(GetDesignSelectorRect, True);
ViewInfo.BuildSelectionLayer;
end;
end;
procedure TdxCustomLayoutControl.Clear;
var
I: Integer;
AItem: TdxCustomLayoutItem;
begin
BeginUpdate;
try
for I := AbsoluteItemCount - 1 downto 0 do
begin
AItem := AbsoluteItems[I];
if (AItem is TdxLayoutItem) and (TdxLayoutItem(AItem).Control <> nil) then
TdxLayoutItem(AItem).Control.Free;
end;
while AbsoluteItemCount <> 0 do
AbsoluteItems[0].Free;
finally
EndUpdate;
end;
end;
function TdxCustomLayoutControl.CreateAlignmentConstraint: TdxLayoutAlignmentConstraint;
begin
Result := GetAlignmentConstraintClass.Create(Owner);
AddAlignmentConstraint(Result);
end;
function TdxCustomLayoutControl.FindItem(AControl: TControl): TdxLayoutItem;
var
I: Integer;
AItem: TdxCustomLayoutItem;
begin
for I := 0 to AbsoluteItemCount - 1 do
begin
AItem := AbsoluteItems[I];
if AItem is TdxLayoutItem then
begin
Result := TdxLayoutItem(AItem);
if Result.Control = AControl then Exit;
end;
end;
Result := nil;
end;
function TdxCustomLayoutControl.FindItem(const AName: string): TdxCustomLayoutItem;
var
I: Integer;
begin
if AName <> '' then
begin
Result := Items;
if SameText(Result.Name, AName) then Exit;
for I := 0 to AbsoluteItemCount - 1 do
begin
Result := AbsoluteItems[I];
if SameText(Result.Name, AName) then Exit;
end;
end;
Result := nil;
end;
function TdxCustomLayoutControl.GetHitTest(const P: TPoint): TdxCustomLayoutHitTest;
begin
Result := ViewInfo.GetHitTest(P);
end;
function TdxCustomLayoutControl.GetHitTest(X, Y: Integer): TdxCustomLayoutHitTest;
begin
Result := ViewInfo.GetHitTest(X, Y);
end;
procedure TdxCustomLayoutControl.BeginUpdate;
begin
Inc(FUpdateLockCount);
end;
procedure TdxCustomLayoutControl.CancelUpdate;
begin
Dec(FUpdateLockCount);
end;
procedure TdxCustomLayoutControl.EndUpdate(ANeedPack: Boolean = True);
begin
Dec(FUpdateLockCount);
LayoutChanged(ANeedPack);
end;
function TdxCustomLayoutControl.CreateGroup(AGroupClass: TdxLayoutGroupClass = nil;
AParent: TdxLayoutGroup = nil): TdxLayoutGroup;
begin
if AGroupClass = nil then
AGroupClass := GetDefaultGroupClass;
Result := TdxLayoutGroup(CreateItem(AGroupClass, AParent));
end;
function TdxCustomLayoutControl.CreateItem(AItemClass: TdxCustomLayoutItemClass = nil;
AParent: TdxLayoutGroup = nil): TdxCustomLayoutItem;
begin
if AItemClass = nil then
AItemClass := GetDefaultItemClass;
Result := AItemClass.Create(Owner);
AddAvailableItem(Result);
Result.Parent := AParent;
Modified;
end;
function TdxCustomLayoutControl.CreateItemForControl(AControl: TControl;
AParent: TdxLayoutGroup = nil): TdxLayoutItem;
begin
Result := TdxLayoutItem(CreateItem(GetDefaultItemClass, AParent));
Result.Control := AControl;
end;
function TdxCustomLayoutControl.CanRestore: Boolean;
begin
Result := OptionsStoring.CanRestoreFromIniFile or OptionsStoring.CanRestoreFromRegistry or (FStoredStream.Size > 0);
end;
procedure TdxCustomLayoutControl.Restore;
begin
if not CanRestore then
Exit;
if OptionsStoring.CanRestoreFromRegistry then
LoadFromRegistry(OptionsStoring.RegistryPath)
else
if OptionsStoring.CanRestoreFromIniFile then
LoadFromIniFile(OptionsStoring.IniFileName)
else
begin
FStoredStream.Position := 0;
LoadFromStream(FStoredStream);
end;
end;
procedure TdxCustomLayoutControl.Store;
begin
if OptionsStoring.CanStoreToIniFile then
SaveToIniFile(OptionsStoring.IniFileName);
if OptionsStoring.CanStoreToRegistry then
SaveToRegistry(OptionsStoring.RegistryPath);
if not IsDestroying then
begin
FStoredStream.Clear;
SaveToStream(FStoredStream);
end;
end;
procedure TdxCustomLayoutControl.LoadFromIniFile(const AFileName: string);
var
AIniFile: TMemIniFile;
begin
if AFileName = '' then Exit;
AIniFile := TMemIniFile.Create(AFileName);
try
LoadFromCustomIniFile(AIniFile, Name);
finally
AIniFile.Free;
end;
end;
procedure TdxCustomLayoutControl.LoadFromRegistry(const ARegistryPath: string);
var
AIniFile: TRegistryIniFile;
begin
if ARegistryPath = '' then Exit;
AIniFile := TRegistryIniFile.Create(ARegistryPath);
try
LoadFromCustomIniFile(AIniFile, '');
finally
AIniFile.Free;
end;
end;
procedure TdxCustomLayoutControl.LoadFromStream(AStream: TStream);
var
AIniFile: TMemIniFile;
AStrings: TStringList;
begin
AIniFile := TMemIniFile.Create('');
AStrings := TStringList.Create;
try
AStrings.LoadFromStream(AStream);
AIniFile.SetStrings(AStrings);
LoadFromCustomIniFile(AIniFile, '');
finally
AStrings.Free;
AIniFile.Free;
end;
end;
procedure TdxCustomLayoutControl.SaveToIniFile(const AFileName: string);
var
AIniFile: TMemIniFile;
begin
if AFileName = '' then Exit;
AIniFile := TMemIniFile.Create(AFileName);
try
SaveToCustomIniFile(AIniFile, Name);
AIniFile.UpdateFile;
finally
AIniFile.Free;
end;
end;
procedure TdxCustomLayoutControl.SaveToRegistry(const ARegistryPath: string);
var
AIniFile: TRegistryIniFile;
begin
if ARegistryPath = '' then Exit;
AIniFile := TRegistryIniFile.Create(ARegistryPath);
try
SaveToCustomIniFile(AIniFile, '');
finally
AIniFile.Free;
end;
end;
procedure TdxCustomLayoutControl.SaveToStream(AStream: TStream);
var
AIniFile: TMemIniFile;
AStrings: TStringList;
begin
AIniFile := TMemIniFile.Create('');
AStrings := TStringList.Create;
try
SaveToCustomIniFile(AIniFile, '');
AIniFile.GetStrings(AStrings);
AStrings.SaveToStream(AStream);
finally
AStrings.Free;
AIniFile.Free;
end;
end;
{ TdxLayoutControlPersistent }
constructor TdxLayoutControlPersistent.Create(AControl: TdxCustomLayoutControl);
begin
inherited Create;
FControl := AControl;
end;
procedure TdxLayoutControlPersistent.Changed;
begin
end;
function TdxLayoutControlPersistent.GetOwner: TPersistent;
begin
Result := FControl;
end;
{ TdxCustomLayoutItemOptions }
constructor TdxCustomLayoutItemOptions.Create(AItem: TdxCustomLayoutItem);
begin
inherited Create;
FItem := AItem;
end;
procedure TdxCustomLayoutItemOptions.Changed;
begin
FItem.Changed;
end;
{ TdxCustomLayoutItemCaptionOptions }
constructor TdxCustomLayoutItemCaptionOptions.Create(AItem: TdxCustomLayoutItem);
begin
inherited;
FShowAccelChar := True;
end;
procedure TdxCustomLayoutItemCaptionOptions.SetAlignHorz(Value: TAlignment);
begin
if FAlignHorz <> Value then
begin
FAlignHorz := Value;
Changed;
end;
end;
procedure TdxCustomLayoutItemCaptionOptions.SetShowAccelChar(Value: Boolean);
begin
if FShowAccelChar <> Value then
begin
FShowAccelChar := Value;
Changed;
end;
end;
{ TdxLayoutGroupHelper }
class function TdxLayoutGroupHelper.GetChildItemsAlignHorz: TdxLayoutAlignHorz;
begin
Result := ahClient;
end;
class function TdxLayoutGroupHelper.GetChildItemsAlignVert: TdxLayoutAlignVert;
begin
Result := avClient;
end;
{ TdxLayoutHorizontalGroupHelper }
class function TdxLayoutHorizontalGroupHelper.GetChildItemsAlignHorz: TdxLayoutAlignHorz;
begin
Result := ahLeft;
end;
class function TdxLayoutHorizontalGroupHelper.GetChildItemsAlignVert: TdxLayoutAlignVert;
begin
Result := avClient;
end;
class function TdxLayoutHorizontalGroupHelper.GetOrthogonalDirection: TdxLayoutDirection;
begin
Result := ldVertical;
end;
class function TdxLayoutHorizontalGroupHelper.GetSpecificClass: TdxLayoutGroupViewInfoSpecificClass;
begin
Result := TdxLayoutGroupViewInfoHorizontalSpecific;
end;
{ TdxLayoutVerticalGroupHelper }
class function TdxLayoutVerticalGroupHelper.GetChildItemsAlignHorz: TdxLayoutAlignHorz;
begin
Result := ahClient;
end;
class function TdxLayoutVerticalGroupHelper.GetChildItemsAlignVert: TdxLayoutAlignVert;
begin
Result := avTop;
end;
class function TdxLayoutVerticalGroupHelper.GetOrthogonalDirection: TdxLayoutDirection;
begin
Result := ldHorizontal;
end;
class function TdxLayoutVerticalGroupHelper.GetSpecificClass: TdxLayoutGroupViewInfoSpecificClass;
begin
Result := TdxLayoutGroupViewInfoVerticalSpecific;
end;
{ TdxLayoutTabbedGroupHelper }
class function TdxLayoutTabbedGroupHelper.GetChildItemsAlignHorz: TdxLayoutAlignHorz;
begin
Result := ahClient;
end;
class function TdxLayoutTabbedGroupHelper.GetChildItemsAlignVert: TdxLayoutAlignVert;
begin
Result := avClient;
end;
class function TdxLayoutTabbedGroupHelper.GetOrthogonalDirection: TdxLayoutDirection;
begin
Result := ldTabbed;
end;
class function TdxLayoutTabbedGroupHelper.GetSpecificClass: TdxLayoutGroupViewInfoSpecificClass;
begin
Result := TdxLayoutGroupViewInfoTabbedSpecific;
end;
{ TdxCustomLayoutItem }
constructor TdxCustomLayoutItem.Create(AOwner: TComponent);
begin
inherited;
FAllowRemove := True;
FAlignHorz := ahParentManaged;
FAlignVert := avParentManaged;
FCaptionOptions := GetCaptionOptionsClass.Create(Self);
FEnabled := True;
FOffsets := TdxLayoutOffsets.Create(Self);
FShowCaption := True;
FVisible := True;
end;
procedure TdxCustomLayoutItem.BeforeDestruction;
begin
Container.BeginUpdate;
inherited;
Container.FinishDragAndDrop(False);
AlignmentConstraint := nil;
end;
destructor TdxCustomLayoutItem.Destroy;
var
AContainer: TdxCustomLayoutControl;
begin
HasMouse := False;
LayoutLookAndFeel := nil;
FreeAndNil(FOffsets);
FreeAndNil(FCaptionOptions);
AContainer := Container;
inherited;
AContainer.EndUpdate;
end;
function TdxCustomLayoutItem.GetRealAlignHorz: TdxLayoutAlignHorz;
begin
if AlignHorz = ahParentManaged then
Result := GetParentManagedAlignHorz
else
Result := AlignHorz;
end;
function TdxCustomLayoutItem.GetRealAlignVert: TdxLayoutAlignVert;
begin
if AlignVert = avParentManaged then
Result := GetParentManagedAlignVert
else
Result := AlignVert;
end;
function TdxCustomLayoutItem.GetActuallyVisible: Boolean;
begin
Result := GetVisible and (IsRoot or (FParent <> nil) and FParent.IsChildActuallyVisible(Self));
end;
function TdxCustomLayoutItem.GetAlignHorz: TdxLayoutAlignHorz;
begin
Result := FAlignHorz;
end;
function TdxCustomLayoutItem.GetAlignVert: TdxLayoutAlignVert;
begin
Result := FAlignVert;
end;
function TdxCustomLayoutItem.GetAutoAligns: TdxLayoutAutoAligns;
begin
Result := [];
if AlignHorz = ahParentManaged then
Include(Result, aaHorizontal);
if AlignVert = avParentManaged then
Include(Result, aaVertical);
end;
function TdxCustomLayoutItem.GetCaptionForCustomizeForm: string;
begin
if (csDesigning in ComponentState) or (FCaption = '') then
Result := Name
else
Result := StripHotKey(FCaption);
end;
function TdxCustomLayoutItem.GetHasMouse: Boolean;
begin
Result := FContainer.ItemWithMouse = Self;
end;
function TdxCustomLayoutItem.GetIndex: Integer;
begin
if FParent = nil then
Result := -1
else
Result := FParent.IndexOf(Self);
end;
function TdxCustomLayoutItem.GetIsAvailable: Boolean;
begin
Result := not IsRoot and ((Parent = nil) or Parent.IsAvailable);
end;
function TdxCustomLayoutItem.GetIsDesigning: Boolean;
begin
Result := csDesigning in ComponentState;
end;
function TdxCustomLayoutItem.GetIsDestroying: Boolean;
begin
Result := csDestroying in ComponentState;
end;
function TdxCustomLayoutItem.GetIsDragged: Boolean;
var
ADragObject: TdxLayoutControlDragAndDropObject;
begin
Result := Container.DragAndDropState <> ddsNone;
if Result then
begin
ADragObject := Container.DragAndDropObject as TdxLayoutControlDragAndDropObject;
Result := ADragObject.SourceItem = Self;
end;
end;
function TdxCustomLayoutItem.GetIsLoading: Boolean;
begin
Result := csLoading in ComponentState;
end;
function TdxCustomLayoutItem.GetIsSelected: Boolean;
begin
Result := Container.IsComponentSelected(Self);
end;
function TdxCustomLayoutItem.GetIsRoot: Boolean;
begin
Result := (FContainer <> nil) and (FContainer.FRootGroup = Self);
end;
function TdxCustomLayoutItem.GetVisibleIndex: Integer;
begin
if FParent = nil then
Result := -1
else
Result := FParent.VisibleIndexOf(Self);
end;
procedure TdxCustomLayoutItem.SetAlignHorz(Value: TdxLayoutAlignHorz);
begin
if AlignHorz <> Value then
begin
FAlignHorz := Value;
Changed;
end;
end;
procedure TdxCustomLayoutItem.SetAlignmentConstraint(Value: TdxLayoutAlignmentConstraint);
begin
if FAlignmentConstraint <> Value then
begin
Container.BeginUpdate;
try
if FAlignmentConstraint <> nil then
FAlignmentConstraint.InternalRemoveItem(Self);
FAlignmentConstraint := Value;
if FAlignmentConstraint <> nil then
FAlignmentConstraint.InternalAddItem(Self);
finally
Container.EndUpdate;
end;
end;
end;
procedure TdxCustomLayoutItem.SetAlignVert(Value: TdxLayoutAlignVert);
begin
if AlignVert <> Value then
begin
FAlignVert := Value;
Changed;
end;
end;
procedure TdxCustomLayoutItem.SetAutoAligns(Value: TdxLayoutAutoAligns);
function GetLoadedAlignHorz: TdxLayoutAlignHorz;
begin
if AlignHorz = ahParentManaged then
Result := ahLeft
else
Result := AlignHorz;
end;
function GetLoadedAlignVert: TdxLayoutAlignVert;
begin
if AlignVert = avParentManaged then
Result := avTop
else
Result := AlignVert;
end;
begin
if AutoAligns <> Value then
begin
Container.BeginUpdate;
try
if aaHorizontal in Value then
AlignHorz := ahParentManaged
else
AlignHorz := GetLoadedAlignHorz;
if aaVertical in Value then
AlignVert := avParentManaged
else
AlignVert := GetLoadedAlignVert;
finally
Container.EndUpdate;
end;
end;
end;
procedure TdxCustomLayoutItem.SetCaption(const Value: string);
begin
if FCaption <> Value then
begin
FCaption := Value;
ResetCachedTextHeight;
Changed;
end;
end;
procedure TdxCustomLayoutItem.SetContainer(Value: TdxCustomLayoutControl);
begin
if FContainer <> Value then
begin
if not IsRoot and (FContainer <> nil) then
FContainer.ExtractAbsoluteItem(Self);
FContainer := Value;
if not IsRoot then
begin
if FContainer <> nil then
FContainer.AddAbsoluteItem(Self);
if Self.Name = '' then
SetComponentName(Self, GetBaseName, IsDesigning, IsLoading);
end
else
Name := GetValidName(Self, GetBaseName + '_Root');
ContainerChanged;
end;
end;
procedure TdxCustomLayoutItem.SetEnabled(Value: Boolean);
begin
if FEnabled <> Value then
begin
FEnabled := Value;
EnabledChanged;
end;
end;
procedure TdxCustomLayoutItem.SetLayoutLookAndFeel(Value: TdxCustomLayoutLookAndFeel);
begin
if FLayoutLookAndFeel <> Value then
begin
if FLayoutLookAndFeel <> nil then
FLayoutLookAndFeel.RemoveUser(Self);
FLayoutLookAndFeel := Value;
if FLayoutLookAndFeel <> nil then
FLayoutLookAndFeel.AddUser(Self);
LayoutLookAndFeelUserChanged;
end;
end;
procedure TdxCustomLayoutItem.SetHasMouse(Value: Boolean);
begin
if HasMouse <> Value then
if Value then
FContainer.ItemWithMouse := Self
else
FContainer.ItemWithMouse := nil;
end;
procedure TdxCustomLayoutItem.SetIndex(Value: Integer);
begin
if FParent <> nil then
FParent.ChangeItemIndex(Self, Value);
end;
procedure TdxCustomLayoutItem.SetParent(Value: TdxLayoutGroup);
var
APrevParent: TdxLayoutGroup;
begin
if (FParent <> Value) and CanMoveTo(Value) then
begin
APrevParent := FParent;
if FParent <> nil then
FParent.ExtractItem(Self)
else
if FContainer <> nil then
FContainer.ExtractAvailableItem(Self);
if Value <> nil then
Value.AddItem(Self)
else
if (APrevParent <> nil) and not APrevParent.IsDestroying then
FContainer.AddAvailableItem(Self);
Changed;
end;
end;
procedure TdxCustomLayoutItem.SetShowCaption(Value: Boolean);
begin
if FShowCaption <> Value then
begin
FShowCaption := Value;
Changed;
end;
end;
procedure TdxCustomLayoutItem.SetVisible(Value: Boolean);
begin
if FVisible <> Value then
begin
FVisible := Value;
Changed;
end;
end;
procedure TdxCustomLayoutItem.SetVisibleIndex(Value: Integer);
begin
if FParent <> nil then
FParent.ChangeItemVisibleIndex(Self, Value);
end;
function TdxCustomLayoutItem.IsAlignHorzStored: Boolean;
begin
Result := IsRoot or (AlignHorz <> ahParentManaged);
end;
function TdxCustomLayoutItem.IsAlignVertStored: Boolean;
begin
Result := IsRoot or (AlignVert <> avParentManaged);
end;
procedure TdxCustomLayoutItem.SetName(const Value: TComponentName);
begin
inherited;
if Container.IsDesigning then
Container.CustomizeFormUpdate([cfutContent]);
end;
procedure TdxCustomLayoutItem.SetParentComponent(Value: TComponent);
begin
inherited;
if Value is TdxLayoutGroup then
Parent := TdxLayoutGroup(Value)
else
if Value is TdxCustomLayoutControl then
TdxCustomLayoutControl(Value).AddAvailableItem(Self);
end;
procedure TdxCustomLayoutItem.LayoutLookAndFeelChanged;
begin
end;
procedure TdxCustomLayoutItem.LayoutLookAndFeelChanging;
begin
ResetCachedTextHeight;
end;
procedure TdxCustomLayoutItem.BeginLayoutLookAndFeelUserDestroying;
begin
FContainer.BeginUpdate;
end;
procedure TdxCustomLayoutItem.EndLayoutLookAndFeelUserDestroying;
begin
FContainer.EndUpdate;
end;
procedure TdxCustomLayoutItem.LayoutLookAndFeelUserChanged;
begin
if IsDestroying or IsLoading or not ActuallyVisible then Exit;
LayoutLookAndFeelChanging;
Changed;
LayoutLookAndFeelChanged;
end;
procedure TdxCustomLayoutItem.LayoutLookAndFeelUserDestroyed;
begin
LayoutLookAndFeel := nil;
end;
function TdxCustomLayoutItem.CanFocusOnClick(X, Y: Integer): Boolean;
begin
Result := False;
end;
function TdxCustomLayoutItem.CanRemove: Boolean;
begin
Result := FAllowRemove;
end;
procedure TdxCustomLayoutItem.ContainerChanged;
begin
// do nothing
end;
procedure TdxCustomLayoutItem.DoCaptionDown;
begin
// do nothing
end;
procedure TdxCustomLayoutItem.DoCaptionClick;
begin
CallNotify(FOnCaptionClick, Self);
end;
procedure TdxCustomLayoutItem.DoPack;
begin
// do nothing
end;
function TdxCustomLayoutItem.DoProcessAccel: Boolean;
var
AItem: TdxCustomLayoutItem;
begin
Result := CanProcessAccel(AItem);
if Result then
AItem.ProcessAccel;
end;
procedure TdxCustomLayoutItem.EnabledChanged;
begin
Changed(ictLight);
end;
function TdxCustomLayoutItem.GetParentManagedAlignHorz: TdxLayoutAlignHorz;
begin
Result := GetParentHelperClass.GetChildItemsAlignHorz;
end;
function TdxCustomLayoutItem.GetParentManagedAlignVert: TdxLayoutAlignVert;
begin
Result := GetParentHelperClass.GetChildItemsAlignVert;
end;
function TdxCustomLayoutItem.GetBaseName: string;
begin
Result := FContainer.Name;
end;
function TdxCustomLayoutItem.GetCursor(X, Y: Integer): TCursor;
begin
Result := ViewInfo.GetCursor(X, Y);
end;
function TdxCustomLayoutItem.GetEnabledForWork: Boolean;
begin
Result := FEnabled and ((FParent = nil) or FParent.EnabledForWork);
end;
function TdxCustomLayoutItem.GetLayoutLookAndFeel: TdxCustomLayoutLookAndFeel;
begin
Result := FLayoutLookAndFeel;
if Result = nil then
if FParent <> nil then
Result := FParent.GetChildLayoutLookAndFeel
else
Result := FContainer.GetLayoutLookAndFeel;
end;
function TdxCustomLayoutItem.GetParentHelperClass: TdxLayoutGroupHelperClass;
begin
if Parent <> nil then
Result := Parent.GetHelperClass
else
Result := TdxLayoutGroupHelper;
end;
function TdxCustomLayoutItem.GetShowCaption: Boolean;
begin
Result := FShowCaption;
end;
function TdxCustomLayoutItem.GetVisible: Boolean;
begin
Result := FVisible or IsDesigning;
end;
function TdxCustomLayoutItem.HasControl: Boolean;
begin
Result := False;
end;
procedure TdxCustomLayoutItem.BeforeCalculateViewInfo;
begin
// do nothing
end;
procedure TdxCustomLayoutItem.AfterCalculateViewInfo;
begin
// do nothing
end;
function TdxCustomLayoutItem.IsParentGroup(AParentGroup: TdxLayoutGroup): Boolean;
begin
Result := AParentGroup.IsChildItem(Self);
end;
function TdxCustomLayoutItem.IsChildItem(AChildItem: TdxCustomLayoutItem): Boolean;
begin
while (AChildItem <> nil) and (AChildItem <> Self) do
AChildItem := AChildItem.Parent;
Result := AChildItem = Self;
end;
function TdxCustomLayoutItem.HasCaption: Boolean;
begin
Result := ShowCaption and (Caption <> '');
end;
procedure TdxCustomLayoutItem.Init;
begin
if GetLayoutLookAndFeel <> nil then
LayoutLookAndFeelChanged;
end;
procedure TdxCustomLayoutItem.MouseEnter;
begin
ViewInfo.MouseEnter;
end;
procedure TdxCustomLayoutItem.MouseLeave;
begin
if FViewInfo <> nil then
FViewInfo.MouseLeave;
end;
procedure TdxCustomLayoutItem.CustomizationMouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
AHitTest: TdxCustomLayoutHitTest;
begin
AHitTest := ViewInfo.GetHitTest(Point(X, Y));
if AHitTest is TdxCustomLayoutItemHitTest then
TdxCustomLayoutItemHitTest(AHitTest).Item.SelectComponent(Shift);
end;
procedure TdxCustomLayoutItem.MouseDown(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
begin
ViewInfo.MouseDown(Button, Shift, X, Y);
if Container.Customization or Container.IsDesigning then
CustomizationMouseDown(Button, Shift, X, Y);
end;
procedure TdxCustomLayoutItem.MouseMove(Shift: TShiftState; X, Y: Integer);
begin
ViewInfo.MouseMove(Shift, X, Y);
end;
procedure TdxCustomLayoutItem.MouseUp(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
begin
ViewInfo.MouseUp(Button, Shift, X, Y);
end;
procedure TdxCustomLayoutItem.ProcessAccel;
begin
end;
function TdxCustomLayoutItem.ProcessDialogChar(ACharCode: Word): Boolean;
begin
Result := HasCaption and FCaptionOptions.ShowAccelChar and
IsAccel(ACharCode, Caption) and DoProcessAccel;
end;
function TdxCustomLayoutItem.GetCaptionOptionsClass: TdxCustomLayoutItemCaptionOptionsClass;
begin
Result := TdxCustomLayoutItemCaptionOptions;
end;
procedure TdxCustomLayoutItem.ResetCachedTextHeight;
begin
FCachedTextHeight := 0;
end;
//IdxLayoutSelectableItem
function TdxCustomLayoutItem.CanDelete: Boolean;
begin
Result := IsDesigning or CanRemove;
end;
function TdxCustomLayoutItem.IsChild(AOwner: TdxCustomLayoutControl): Boolean;
begin
Result := Container = AOwner;
end;
procedure TdxCustomLayoutItem.SelectComponent(AShift: TShiftState = []);
begin
Container.SelectComponent(Self, AShift);
end;
procedure TdxCustomLayoutItem.SelectParent;
begin
if Parent = nil then
Container.SelectComponent(Container)
else
Container.SelectComponent(Parent);
end;
procedure TdxCustomLayoutItem.SelectionChanged;
begin
// do nothing
end;
function TdxCustomLayoutItem.IsSelectableItemVisible: Boolean;
begin
Result := ActuallyVisible;
end;
function TdxCustomLayoutItem.GetParentComponent: TComponent;
begin
if FParent = nil then
Result := FContainer
else
Result := FParent;
end;
function TdxCustomLayoutItem.HasParent: Boolean;
begin
Result := True;
end;
procedure TdxCustomLayoutItem.Changed(AType: TdxLayoutItemChangeType);
begin
if IsDestroying or Container.IsLoading or Container.IsDestroying or Container.IsUpdateLocked then Exit;
case AType of
ictHard: Container.LayoutChanged(False);
ictMedium:
if ViewInfo <> nil then
begin
Container.BeginUpdate;
try
BeforeCalculateViewInfo;
ViewInfo.Calculate(ViewInfo.Bounds);
AfterCalculateViewInfo;
if Container.HandleAllocated then
Container.PlaceControls(ViewInfo);
Container.InvalidateRect(ViewInfo.Bounds, False);
finally
Container.CancelUpdate;
end;
Container.PostBuildSelectionLayer;
end;
ictLight:
if ViewInfo <> nil then
Container.InvalidateRect(ViewInfo.Bounds, False);
end;
end;
function TdxCustomLayoutItem.CanMoveTo(AParent: TdxCustomLayoutItem): Boolean;
begin
Result := AParent <> Self;
end;
procedure TdxCustomLayoutItem.MakeVisible;
var
R, AClientR: TRect;
procedure MakeVisibleInOneDirection(AItemMin, AItemMax,
AClientMin, AClientMax: Integer; AIsHorizontal: Boolean);
var
AOffset: Integer;
procedure ChangeOffset(ADelta: Integer);
begin
Inc(AOffset, ADelta);
Dec(AItemMin, ADelta);
Dec(AItemMax, ADelta);
end;
procedure ApplyOffset;
begin
with FContainer do
if AIsHorizontal then
LeftPos := LeftPos + AOffset
else
TopPos := TopPos + AOffset;
end;
begin
AOffset := 0;
if AItemMax > AClientMax then
ChangeOffset(AItemMax - AClientMax);
if AItemMin < AClientMin then
ChangeOffset(-(AClientMin - AItemMin));
ApplyOffset;
end;
begin
if not ActuallyVisible then Exit;
R := ViewInfo.Bounds;
AClientR := FContainer.ClientBounds;
MakeVisibleInOneDirection(R.Left, R.Right, AClientR.Left, AClientR.Right, True);
MakeVisibleInOneDirection(R.Top, R.Bottom, AClientR.Top, AClientR.Bottom, False);
end;
function TdxCustomLayoutItem.Move(AParent: TdxLayoutGroup; AIndex: Integer;
APack: Boolean = False): Boolean;
var
ASourceContainer, ADestinationContainer: TdxCustomLayoutControl;
begin
Result := CanMoveTo(AParent);
if not Result then Exit;
ASourceContainer := Container;
ADestinationContainer := AParent.Container;
ASourceContainer.BeginUpdate;
ADestinationContainer.BeginUpdate;
try
Parent := AParent;
Index := AIndex;
finally
ASourceContainer.EndUpdate(APack);
ADestinationContainer.EndUpdate(APack);
end;
end;
function TdxCustomLayoutItem.MoveTo(AParent: TdxLayoutGroup; AVisibleIndex: Integer;
APack: Boolean = False): Boolean;
var
AIndex: Integer;
begin
if AParent = nil then
AIndex := -1
else
AIndex := AParent.GetItemIndex(AVisibleIndex);
Result := Move(AParent, AIndex, APack);
end;
procedure TdxCustomLayoutItem.Pack;
begin
DoPack;
end;
function TdxCustomLayoutItem.PutIntoHiddenGroup(ALayoutDirection: TdxLayoutDirection): TdxLayoutGroup;
var
AIndex: Integer;
begin
if FParent = nil then
Result := nil
else
begin
AIndex := Index;
Result := FParent.CreateGroup;
with Result do
begin
Hidden := True;
LayoutDirection := ALayoutDirection;
Index := AIndex;
end;
Move(Result, 0);
end;
end;
{ TdxLayoutDragAndDropHelper }
constructor TdxLayoutDragAndDropHelper.Create(
AControl: TdxCustomLayoutControl);
begin
inherited Create(AControl);
Reset;
end;
procedure TdxLayoutDragAndDropHelper.InitializeDragItem(AItem: TdxCustomLayoutItem;
X, Y: Integer);
begin
FMouseDownPos := Point(X, Y);
FDragItem := AItem;
end;
procedure TdxLayoutDragAndDropHelper.Reset;
begin
FDragItem := nil;
FMouseDownPos := cxInvalidPoint;
end;
procedure TdxLayoutDragAndDropHelper.TryBeginDragAndDrop(X, Y: Integer;
ASource: TdxLayoutDragSource);
begin
if CanBeginDragAndDrop(X, Y) then
BeginDragAndDrop(ASource);
end;
function TdxLayoutDragAndDropHelper.CanBeginDragAndDrop(X, Y: Integer): Boolean;
begin
Result := Control.CanDragAndDrop and (Control.DragAndDropState = ddsNone) and
not cxPointIsEqual(FMouseDownPos, cxInvalidPoint) and not IsPointInDragDetectArea(FMouseDownPos, X, Y) and
(DragItem <> nil) and not DragItem.IsRoot;
end;
procedure TdxLayoutDragAndDropHelper.BeginDragAndDrop(ASource: TdxLayoutDragSource);
begin
DragAndDropObject.Init(ASource, DragItem);
Control.BeginDragAndDrop;
end;
function TdxLayoutDragAndDropHelper.GetDragAndDropObject: TdxLayoutControlDragAndDropObject;
begin
Result := TdxLayoutControlDragAndDropObject(Control.DragAndDropObject);
end;
{ TdxLayoutCustomizeListBox }
function TdxLayoutCustomizeListBox.GetDragAndDropItemObject: TdxCustomLayoutItem;
begin
Result := TdxCustomLayoutItem(inherited DragAndDropItemObject);
end;
procedure TdxLayoutCustomizeListBox.BeginDragAndDrop;
begin
inherited;
with Control do
if CanDragAndDrop then
begin
(DragAndDropObject as TdxLayoutControlDragAndDropObject).Init(dsCustomizeFormAvailableItems,
Self.DragAndDropItemObject);
BeginDragAndDrop;
end;
end;
{ TdxLayoutControlRunTimeSelectionHelper }
constructor TdxLayoutRunTimeSelectionHelper.Create(AOwner: TPersistent);
begin
inherited Create;
FOwner := AOwner;
FSelectionList := TcxComponentList.Create;
FListeners := TList.Create;
FSelectionList.OnNotify := SelectionListNotifyHandler;
FSelectionList.OnComponentListChanged := SelectionListChangedHandler;
end;
destructor TdxLayoutRunTimeSelectionHelper.Destroy;
begin
FreeAndNil(FSelectionList);
FreeAndNil(FListeners);
inherited;
end;
procedure TdxLayoutRunTimeSelectionHelper.AddSelectionChangedListener(AListener: TPersistent);
begin
if (AListener <> nil) and Supports(AListener, IdxLayoutSelectionChanged) and
(FListeners.IndexOf(AListener) < 0) then
FListeners.Add(AListener);
end;
procedure TdxLayoutRunTimeSelectionHelper.RemoveSelectionChangedListener(AListener: TPersistent);
begin
FListeners.Remove(AListener);
end;
function TdxLayoutRunTimeSelectionHelper.CanDeleteComponent(
AComponent: TComponent): Boolean;
var
ASelectableItem: IdxLayoutSelectableItem;
begin
Result := not (csDestroying in AComponent.ComponentState) and
Supports(AComponent, IdxLayoutSelectableItem, ASelectableItem) and
ASelectableItem.CanDelete;
end;
procedure TdxLayoutRunTimeSelectionHelper.ClearSelection;
begin
FSelectionList.Clear;
end;
procedure TdxLayoutRunTimeSelectionHelper.GetSelection(AList: TList);
var
I: Integer;
begin
for I := 0 to FSelectionList.Count - 1 do
AList.Add(FSelectionList[I]);
end;
function TdxLayoutRunTimeSelectionHelper.IsComponentSelected(AComponent: TPersistent): Boolean;
begin
Result := FSelectionList.IndexOf(TComponent(AComponent)) <> -1;
end;
procedure TdxLayoutRunTimeSelectionHelper.SelectComponent(
AComponent: TPersistent; AShift: TShiftState);
begin
FSelectionList.BeginUpdate;
try
if (ssCtrl in AShift) and IsComponentSelected(AComponent) then
FSelectionList.Delete(FSelectionList.IndexOf(TComponent(AComponent)))
else
begin
if not (ssCtrl in AShift) then
ClearSelection;
if not IsComponentSelected(AComponent) then
FSelectionList.Add(TComponent(AComponent));
end;
finally
FSelectionList.EndUpdate;
end;
end;
procedure TdxLayoutRunTimeSelectionHelper.SetSelection(AList: TList);
var
I: Integer;
begin
FSelectionList.BeginUpdate;
try
ClearSelection;
for I := 0 to AList.Count - 1 do
if FSelectionList.IndexOf(AList[I]) = -1 then
FSelectionList.Add(AList[I]);
finally
FSelectionList.EndUpdate;
end;
end;
function TdxLayoutRunTimeSelectionHelper.UniqueName(const BaseName: string): string;
begin
Result := '';
end;
function TdxLayoutRunTimeSelectionHelper.GetComponentClass(AComponent: TComponent): TComponentClass;
begin
Result := TComponentClass(AComponent.ClassType);
end;
procedure TdxLayoutRunTimeSelectionHelper.NotifyListeners(AList: TList; AAction: TdxLayoutSelectionAction);
var
I: Integer;
AIntf: IdxLayoutSelectionChanged;
begin
for I := 0 to FListeners.Count - 1 do
if Supports(TObject(FListeners[I]), IdxLayoutSelectionChanged, AIntf) then
begin
AIntf.SelectionChanged(AList, AAction);
AIntf := nil;
end;
end;
procedure TdxLayoutRunTimeSelectionHelper.SelectionListNotify(AComponent: TComponent;
AAction: TListNotification);
var
ASelectableItem: IdxLayoutSelectableItem;
begin
if not (csDestroying in AComponent.ComponentState) and
Supports(AComponent, IdxLayoutSelectableItem, ASelectableItem) then
ASelectableItem.SelectionChanged;
end;
function TdxLayoutRunTimeSelectionHelper.QueryInterface(const IID: TGUID; out Obj): HResult;
begin
if GetInterface(IID, Obj) then
Result := 0
else
Result := E_NOINTERFACE;
end;
function TdxLayoutRunTimeSelectionHelper._AddRef: Integer;
begin
Result := InterlockedIncrement(FRefCount);
end;
function TdxLayoutRunTimeSelectionHelper._Release: Integer;
begin
Result := InterlockedDecrement(FRefCount);
if Result = 0 then
Destroy;
end;
function TdxLayoutRunTimeSelectionHelper.GetComponent: TComponent;
begin
Result := TComponent(Owner);
end;
procedure TdxLayoutRunTimeSelectionHelper.SelectionListNotifyHandler(Sender: TObject;
AComponent: TComponent; AAction: TListNotification);
begin
SelectionListNotify(AComponent, AAction);
end;
procedure TdxLayoutRunTimeSelectionHelper.SelectionListChangedHandler(Sender: TObject;
AComponent: TComponent; AAction: TcxComponentCollectionNotification);
const
Action: array[TcxComponentCollectionNotification] of TdxLayoutSelectionAction = (lsaAdded, lsaChanged, lsaExtracted, lsaExtracted, lsaExtracted);
var
AList: TList;
begin
if AAction in [ccnAdded, ccnChanged, ccnExtracted] then
begin
AList := TList.Create;
try
GetSelection(AList);
NotifyListeners(AList, Action[AAction]);
finally
AList.Free;
end;
end;
end;
{ TdxLayoutAlignmentConstraint }
constructor TdxLayoutAlignmentConstraint.Create(AOwner: TComponent);
begin
inherited;
CreateItems;
end;
destructor TdxLayoutAlignmentConstraint.Destroy;
begin
DestroyItems;
if FControl <> nil then
FControl.RemoveAlignmentConstraint(Self);
inherited;
end;
function TdxLayoutAlignmentConstraint.GetCount: Integer;
begin
Result := FItems.Count;
end;
function TdxLayoutAlignmentConstraint.GetItem(Index: Integer): TdxCustomLayoutItem;
begin
Result := FItems[Index];
end;
procedure TdxLayoutAlignmentConstraint.SetKind(Value: TdxLayoutAlignmentConstraintKind);
begin
if FKind <> Value then
begin
FKind := Value;
Changed;
end;
end;
procedure TdxLayoutAlignmentConstraint.CreateItems;
begin
FItems := TList.Create;
end;
procedure TdxLayoutAlignmentConstraint.DestroyItems;
var
I: Integer;
begin
BeginUpdate;
try
for I := Count - 1 downto 0 do
RemoveItem(Items[I]);
finally
EndUpdate;
end;
FreeAndNil(FItems);
end;
procedure TdxLayoutAlignmentConstraint.InternalAddItem(AItem: TdxCustomLayoutItem);
begin
FItems.Add(AItem);
end;
procedure TdxLayoutAlignmentConstraint.InternalRemoveItem(AItem: TdxCustomLayoutItem);
begin
FItems.Remove(AItem);
if not (csDestroying in ComponentState) and (Count < 2) then
Free;
end;
procedure TdxLayoutAlignmentConstraint.SetParentComponent(Value: TComponent);
begin
inherited;
if Value is TdxCustomLayoutControl then
TdxCustomLayoutControl(Value).AddAlignmentConstraint(Self);
end;
procedure TdxLayoutAlignmentConstraint.BeginUpdate;
begin
FControl.BeginUpdate;
end;
function TdxLayoutAlignmentConstraint.CanAddItem(AItem: TdxCustomLayoutItem): Boolean;
begin
Result := (AItem <> nil) and (AItem.Container = Control);
end;
procedure TdxLayoutAlignmentConstraint.Changed;
begin
FControl.LayoutChanged;
end;
procedure TdxLayoutAlignmentConstraint.EndUpdate;
begin
FControl.EndUpdate;
end;
function TdxLayoutAlignmentConstraint.GetParentComponent: TComponent;
begin
Result := FControl;
end;
function TdxLayoutAlignmentConstraint.HasParent: Boolean;
begin
Result := FControl <> nil;
end;
procedure TdxLayoutAlignmentConstraint.AddItem(AItem: TdxCustomLayoutItem);
begin
if CanAddItem(AItem) then
AItem.AlignmentConstraint := Self;
end;
procedure TdxLayoutAlignmentConstraint.RemoveItem(AItem: TdxCustomLayoutItem);
begin
if FItems.IndexOf(AItem) <> -1 then
AItem.AlignmentConstraint := nil;
end;
{ TdxCustomisationCanvas }
constructor TdxCustomizationCanvas.Create;
begin
inherited Create(TCanvas.Create);
end;
destructor TdxCustomizationCanvas.Destroy;
begin
Canvas.Free;
inherited;
end;
procedure TdxCustomizationCanvas.BeginPaint(ADC: THandle);
begin
SetLength(FSavedDCs, FCounter + 1);
if HandleValid then
begin
SaveState;
FSavedDCs[FCounter].PrevDC := Handle;
end
else
FSavedDCs[FCounter].PrevDC := 0;
FSavedDCs[FCounter].PrevCanvas := nil;
FSavedDCs[FCounter].NewDC := ADC;
FSavedDCs[FCounter].NewDCIndex := Windows.SaveDC(ADC);
SynchronizeObjects(ADC);
Canvas.Handle := ADC;
Inc(FCounter);
end;
procedure TdxCustomizationCanvas.BeginPaint(ACanvas: TCanvas);
begin
SetLength(FSavedDCs, FCounter + 1);
FSavedDCs[FCounter].PrevCanvas := Canvas;
Canvas := ACanvas;
SaveClipRegion;
SaveState;
Inc(FCounter);
end;
procedure TdxCustomizationCanvas.EndPaint;
begin
if FCounter > 0 then
begin
Dec(FCounter);
if FSavedDCs[FCounter].PrevCanvas <> nil then
begin
RestoreState;
RestoreClipRegion;
Canvas := FSavedDCs[FCounter].PrevCanvas;
end
else
begin
Canvas.Handle := FSavedDCs[FCounter].PrevDC;
Windows.RestoreDC(FSavedDCs[FCounter].NewDC, FSavedDCs[FCounter].NewDCIndex);
if HandleValid then
RestoreState;
end;
SetLength(FSavedDCs, FCounter);
end;
end;
function TdxCustomizationCanvas.HandleValid;
begin
Result := {$IFDEF DELPHI6}Canvas.HandleAllocated{$ELSE}FCounter > 0{$ENDIF};
end;
{ TdxCustomSatelliteControlItem }
constructor TdxCustomSatelliteControlItem.Create(AOwner: TdxSatelliteControls; AControl: TControl);
begin
inherited Create(nil);
FOwner := AOwner;
FControl := AControl;
FControl.FreeNotification(Self);
end;
destructor TdxCustomSatelliteControlItem.Destroy;
begin
FControl.RemoveFreeNotification(Self);
FControl := nil;
inherited Destroy;
end;
procedure TdxCustomSatelliteControlItem.Notification(AComponent: TComponent; Operation: TOperation);
begin
inherited;
if (AComponent = FControl) and (Operation = opRemove) then
Free;
end;
{ TdxControlDesignSelectorItem }
constructor TdxControlDesignSelectorItem.Create(AOwner: TdxSatelliteControls; AControl: TControl);
begin
inherited Create(AOwner, AControl);
FSelectorBounds := cxInvalidRect;
FChildren := TcxComponentList.Create;
FChildren.OwnsObjects := True;
FDefaultControlWndProc := Control.WindowProc;
Control.WindowProc := ControlWndProc;
end;
destructor TdxControlDesignSelectorItem.Destroy;
begin
Control.WindowProc := FDefaultControlWndProc;
FDefaultControlWndProc := nil;
FreeAndNil(FChildren);
inherited Destroy;
end;
procedure TdxControlDesignSelectorItem.ControlWndProc(var Message: TMessage);
function PtInSelectorBounds(const P: TPoint): Boolean;
begin
Result := PtInRect(SelectorBounds, P);
end;
var
DC: HDC;
ANeedProcessDefaultControlWndProc: Boolean;
begin
ANeedProcessDefaultControlWndProc := True;
if IsActive and not EqualRect(cxInvalidRect, SelectorBounds) then
case Message.Msg of
WM_NCHITTEST:
if PtInSelectorBounds(Control.ScreenToClient(Point(Message.LParamLo, Message.LParamHi))) then
begin
Message.Result := HTTRANSPARENT;
ANeedProcessDefaultControlWndProc := False;
end;
CM_HITTEST:
if PtInSelectorBounds(Point(Message.LParamLo, Message.LParamHi)) then
begin
Message.Result := HTNOWHERE;
ANeedProcessDefaultControlWndProc := False;
end;
end;
if ANeedProcessDefaultControlWndProc then
FDefaultControlWndProc(Message);
case Message.Msg of
CM_CONTROLCHANGE:
CheckChildren;
WM_WINDOWPOSCHANGED:
ParentCheckChildren;
WM_PAINT:
if IsActive then
begin
DC := TWMPaint(Message).DC;
if DC <> 0 then
DrawDesignSelector(DC)
else
if Control is TWinControl then
begin
DC := GetWindowDC((Control as TWinControl).Handle);
DrawDesignSelector(DC);
ReleaseDC((Control as TWinControl).Handle, DC);
end;
end;
end;
end;
procedure TdxControlDesignSelectorItem.CheckChildren;
var
I: Integer;
AItem: TdxControlDesignSelectorItem;
AControl: TControl;
begin
FChildren.Clear;
if Control is TWinControl then
for I := 0 to (Control as TWinControl).ControlCount - 1 do
begin
AControl := (Control as TWinControl).Controls[I];
if csDestroying in AControl.ComponentState then
Continue;
AItem := TdxControlDesignSelectorItem.Create(nil, AControl);
FChildren.Add(AItem);
AItem.Parent := Self;
AItem.LayoutItem := LayoutItem;
AItem.SelectorBounds := GetSelectorBoundsForChild(AItem);
end;
end;
procedure TdxControlDesignSelectorItem.ParentCheckChildren;
begin
if Parent <> nil then
Parent.CheckChildren;
end;
function TdxControlDesignSelectorItem.IsActive: Boolean;
begin
Result := IsValid and LayoutItem.Container.ShowDesignSelectors;
end;
function TdxControlDesignSelectorItem.IsValid: Boolean;
begin
Result := (LayoutItem <> nil) and (LayoutItem.ViewInfo <> nil);
end;
function TdxControlDesignSelectorItem.CanDrawDesignSelector: Boolean;
begin
Result := IsActive and LayoutItem.ActuallyVisible;
end;
procedure TdxControlDesignSelectorItem.DoDrawDesignSelector(DC: HDC);
function IsSelected: Boolean;
begin
Result := (not LayoutItem.Container.Customization and LayoutItem.ViewInfo.Selected) or
(LayoutItem.Container.Customization and LayoutItem.Container.IsComponentSelected(LayoutItem.Control));
end;
begin
dxGlobalCanvas.BeginPaint(DC);
try
cxDrawDesignRect(dxGlobalCanvas, SelectorBounds, IsSelected);
finally
dxGlobalCanvas.EndPaint;
end;
end;
procedure TdxControlDesignSelectorItem.DrawDesignSelector(DC: HDC);
begin
if CanDrawDesignSelector then
DoDrawDesignSelector(DC);
end;
function TdxControlDesignSelectorItem.GetSelectorBoundsForChild(AChild: TdxControlDesignSelectorItem): TRect;
begin
Result := SelectorBounds;
Result := cxRectOffset(Result, AChild.Control.BoundsRect.TopLeft, False);
end;
procedure TdxControlDesignSelectorItem.SetLayoutItem(AValue: TdxLayoutItem);
begin
if AValue <> FLayoutItem then
begin
FLayoutItem := AValue;
CheckChildren;
end;
end;
procedure TdxControlDesignSelectorItem.SetSelectorBounds(const AValue: TRect);
begin
if not EqualRect(AValue, FSelectorBounds) then
begin
FSelectorBounds := AValue;
CheckChildren;
if Control.Visible then
Control.Invalidate;
end;
end;
{ TdxCustomizationControlItem }
constructor TdxCustomizationControlItem.Create(AOwner: TdxSatelliteControls; AControl: TControl);
begin
inherited Create(AOwner, AControl);
FPrevEnabled := not EnableWindow(Control.Handle, False);
end;
destructor TdxCustomizationControlItem.Destroy;
begin
if Control.HandleAllocated then
EnableWindow(Control.Handle, FPrevEnabled);
inherited Destroy;
end;
function TdxCustomizationControlItem.GetControl: TWinControl;
begin
Result := inherited Control as TWinControl;
end;
{ TdxSatelliteControls }
function TdxSatelliteControls.AddControl(AControl: TControl;
AItemClass: TdxCustomSatelliteControlItemClass): TdxCustomSatelliteControlItem;
var
AIndex: Integer;
begin
AIndex := FindByControl(AControl);
if AIndex = -1 then
begin
Result := AItemClass.Create(Self, AControl);
Add(Result);
end
else
Result := Items[AIndex];
end;
function TdxSatelliteControls.FindByControl(AControl: TControl): Integer;
var
I: Integer;
begin
Result := -1;
for I := 0 to Count - 1 do
if Items[I].Control = AControl then
begin
Result := I;
Break;
end;
end;
procedure TdxSatelliteControls.RemoveControl(AControl: TControl);
begin
Delete(FindByControl(AControl));
end;
function TdxSatelliteControls.GetItem(Index: Integer): TdxCustomSatelliteControlItem;
begin
Result := inherited Items[Index] as TdxCustomSatelliteControlItem;
end;
{ TdxLayoutControlAdapterDefs }
constructor TdxLayoutControlAdapterDefs.Create;
begin
inherited;
FItems := TList.Create;
end;
destructor TdxLayoutControlAdapterDefs.Destroy;
begin
ClearItems;
FItems.Free;
inherited;
end;
function TdxLayoutControlAdapterDefs.GetCount: Integer;
begin
Result := FItems.Count;
end;
function TdxLayoutControlAdapterDefs.GetItem(Index: Integer): TControlAdapterRecord;
begin
Result := PControlAdapterRecord(FItems[Index])^;
end;
procedure TdxLayoutControlAdapterDefs.ClearItems;
var
I: Integer;
begin
for I := Count - 1 downto 0 do
Delete(I);
end;
procedure TdxLayoutControlAdapterDefs.Delete(AIndex: Integer);
begin
Dispose(PControlAdapterRecord(FItems[AIndex]));
FItems.Delete(AIndex);
end;
function TdxLayoutControlAdapterDefs.GetAdapterClass(AControl: TControl): TdxCustomLayoutControlAdapterClass;
var
I: Integer;
AControlAdapterRecord: TControlAdapterRecord;
begin
for I := Count - 1 downto 0 do
begin
AControlAdapterRecord := Items[I];
if AControl.InheritsFrom(AControlAdapterRecord.ControlClass) then
begin
Result := AControlAdapterRecord.AdapterClass;
Exit;
end;
end;
Result := TdxCustomLayoutControlAdapter;
end;
procedure TdxLayoutControlAdapterDefs.Register(AControlClass: TControlClass;
AAdapterClass: TdxCustomLayoutControlAdapterClass);
var
AControlAdapterRecord: PControlAdapterRecord;
begin
New(AControlAdapterRecord);
with AControlAdapterRecord^ do
begin
ControlClass := AControlClass;
AdapterClass := AAdapterClass;
end;
FItems.Add(AControlAdapterRecord);
end;
procedure TdxLayoutControlAdapterDefs.Unregister(AControlClass: TControlClass;
AAdapterClass: TdxCustomLayoutControlAdapterClass);
var
I: Integer;
AControlAdapterRecord: TControlAdapterRecord;
begin
for I := 0 to Count - 1 do
begin
AControlAdapterRecord := Items[I];
with AControlAdapterRecord do
if (ControlClass = AControlClass) and (AdapterClass = AAdapterClass) then
begin
Delete(I);
Break;
end;
end;
if Count = 0 then
FreeAndNil(FdxLayoutControlAdapterDefs);
end;
{ TdxLayoutItemCaptionOptions }
constructor TdxLayoutItemCaptionOptions.Create(AItem: TdxCustomLayoutItem);
begin
inherited;
FAlignVert := tavCenter;
end;
procedure TdxLayoutItemCaptionOptions.SetAlignVert(Value: TdxAlignmentVert);
begin
if FAlignVert <> Value then
begin
FAlignVert := Value;
Changed;
end;
end;
procedure TdxLayoutItemCaptionOptions.SetLayout(Value: TdxCaptionLayout);
begin
if FLayout <> Value then
begin
FLayout := Value;
Changed;
end;
end;
procedure TdxLayoutItemCaptionOptions.SetWidth(Value: Integer);
begin
if Value < 0 then Value := 0;
if FWidth <> Value then
begin
FWidth := Value;
Item.ResetCachedTextHeight;
Changed;
end;
end;
{ TdxLayoutItemControlOptions }
constructor TdxLayoutItemControlOptions.Create(AItem: TdxCustomLayoutItem);
begin
inherited;
FAutoAlignment := True;
FMinHeight := dxLayoutItemControlDefaultMinHeight;
FMinWidth := dxLayoutItemControlDefaultMinWidth;
FShowBorder := True;
end;
procedure TdxLayoutItemControlOptions.SetAutoAlignment(Value: Boolean);
begin
if FAutoAlignment <> Value then
begin
FAutoAlignment := Value;
Changed;
end;
end;
procedure TdxLayoutItemControlOptions.SetAutoColor(Value: Boolean);
begin
if FAutoColor <> Value then
begin
FAutoColor := Value;
Item.LayoutLookAndFeelUserChanged;
end;
end;
procedure TdxLayoutItemControlOptions.SetFixedSize(Value: Boolean);
begin
if FFixedSize <> Value then
begin
FFixedSize := Value;
Changed;
end;
end;
procedure TdxLayoutItemControlOptions.SetMinHeight(Value: Integer);
begin
if Value < 0 then Value := 0;
if FMinHeight <> Value then
begin
FMinHeight := Value;
Changed;
end;
end;
procedure TdxLayoutItemControlOptions.SetMinWidth(Value: Integer);
begin
if Value < 0 then Value := 0;
if FMinWidth <> Value then
begin
FMinWidth := Value;
Changed;
end;
end;
procedure TdxLayoutItemControlOptions.SetOpaque(Value: Boolean);
begin
if FOpaque <> Value then
begin
FOpaque := Value;
Changed;
end;
end;
procedure TdxLayoutItemControlOptions.SetShowBorder(Value: Boolean);
begin
if FShowBorder <> Value then
begin
FShowBorder := Value;
Changed;
end;
end;
{ TdxCustomLayoutElementPainter }
constructor TdxCustomLayoutElementPainter.Create(ACanvas: TcxCanvas; AViewInfo: TdxCustomLayoutElementViewInfo);
begin
inherited Create;
FCanvas := ACanvas;
FViewInfo := AViewInfo;
end;
{ TdxCustomLayoutItemElementPainter }
function TdxCustomLayoutItemElementPainter.GetLayoutLookAndFeel: TdxCustomLayoutLookAndFeel;
begin
Result := ViewInfo.LayoutLookAndFeel;
end;
function TdxCustomLayoutItemElementPainter.GetViewInfo: TdxCustomLayoutItemElementViewInfo;
begin
Result := inherited ViewInfo as TdxCustomLayoutItemElementViewInfo;
end;
{ TdxCustomLayoutItemCaptionPainter }
function TdxCustomLayoutItemCaptionPainter.GetViewInfo: TdxCustomLayoutItemCaptionViewInfo;
begin
Result := TdxCustomLayoutItemCaptionViewInfo(inherited ViewInfo);
end;
procedure TdxCustomLayoutItemCaptionPainter.AfterDrawText;
begin
with Canvas do
Brush.Style := bsSolid;
end;
procedure TdxCustomLayoutItemCaptionPainter.BeforeDrawText;
begin
with Canvas do
begin
Brush.Style := bsClear;
Font := ViewInfo.Font;
Font.Color := ViewInfo.TextColor;
if ViewInfo.IsTextUnderlined then
Font.Style := Font.Style + [fsUnderline];
end;
end;
procedure TdxCustomLayoutItemCaptionPainter.DrawBackground;
begin
end;
procedure TdxCustomLayoutItemCaptionPainter.DrawText;
begin
if ViewInfo.Text <> '' then
begin
BeforeDrawText;
DoDrawText;
AfterDrawText;
end;
end;
procedure TdxCustomLayoutItemCaptionPainter.DoDrawText;
begin
with ViewInfo do
Self.Canvas.DrawText(Text, TextAreaBounds, CalculateTextFlags, EnabledForWork);
end;
procedure TdxCustomLayoutItemCaptionPainter.Paint;
begin
if RectVisible(Canvas.Handle, ViewInfo.Bounds) then
begin
DrawBackground;
DrawText;
end;
end;
{ TdxCustomLayoutItemPainter }
function TdxCustomLayoutItemPainter.GetLayoutLookAndFeel: TdxCustomLayoutLookAndFeel;
begin
Result := ViewInfo.LayoutLookAndFeel;
end;
function TdxCustomLayoutItemPainter.GetViewInfo: TdxCustomLayoutItemViewInfo;
begin
Result := inherited ViewInfo as TdxCustomLayoutItemViewInfo;
end;
procedure TdxCustomLayoutItemPainter.DoDrawBackground;
begin
if ViewInfo.HasBackground then
Canvas.FillRect(ViewInfo.BackgroundBounds, ViewInfo.GetBackgroundColor);
end;
procedure TdxCustomLayoutItemPainter.DoDrawCaption;
begin
with GetCaptionPainterClass.Create(Canvas, ViewInfo.CaptionViewInfo) do
try
Paint;
finally
Free;
end;
end;
procedure TdxCustomLayoutItemPainter.DoDrawSpecificPart;
begin
// do nothing
end;
procedure TdxCustomLayoutItemPainter.DoDrawSelectionFrame;
begin
FrameRectByColor(Canvas.Handle, ViewInfo.SelectionBorderRect, dxLayoutSelectionBorderDefaultColor);
end;
procedure TdxCustomLayoutItemPainter.DrawBackground;
begin
if CanDrawBackground then
DoDrawBackground;
end;
procedure TdxCustomLayoutItemPainter.DrawCaption;
begin
if CanDrawCaption then
DoDrawCaption;
end;
procedure TdxCustomLayoutItemPainter.DrawItem;
begin
DrawBackground;
DrawContent;
end;
procedure TdxCustomLayoutItemPainter.DrawContent;
begin
DrawCaption;
end;
function TdxCustomLayoutItemPainter.CanDrawBackground: Boolean;
begin
Result := ViewInfo.CanDrawBackground;
end;
function TdxCustomLayoutItemPainter.CanDrawCaption: Boolean;
begin
Result := ViewInfo.HasCaption;
end;
function TdxCustomLayoutItemPainter.CanPaint: Boolean;
begin
Result := ViewInfo.CanPaint;
end;
function TdxCustomLayoutItemPainter.CanPaintSpecificPart: Boolean;
begin
Result := CanPaint and ViewInfo.IsDragImagePainted;
end;
procedure TdxCustomLayoutItemPainter.PaintSpecificPart;
begin
if CanPaintSpecificPart then
DoDrawSpecificPart;
end;
procedure TdxCustomLayoutItemPainter.PaintDesignFeatures;
begin
// do nothing
end;
procedure TdxCustomLayoutItemPainter.Paint;
begin
if CanPaint and RectVisible(Canvas.Handle, ViewInfo.Bounds) then
begin
DrawItem;
//#DG selection breaks Canvas.ExcludeClipRect(ViewInfo.Bounds);
end;
end;
{ TdxLayoutItemControlPainter }
function TdxLayoutItemControlPainter.GetViewInfo: TdxLayoutItemControlViewInfo;
begin
Result := TdxLayoutItemControlViewInfo(inherited ViewInfo);
end;
procedure TdxLayoutItemControlPainter.DrawBorders;
begin
LayoutLookAndFeel.DrawItemControlBorder(Canvas, ViewInfo.ItemViewInfo.Options, ViewInfo.Bounds);
end;
procedure TdxLayoutItemControlPainter.Paint;
begin
if ViewInfo.HasBorder and RectVisible(Canvas.Handle, ViewInfo.Bounds) then
DrawBorders;
end;
{ TdxLayoutItemPainter }
function TdxLayoutItemPainter.GetViewInfo: TdxLayoutItemViewInfo;
begin
Result := TdxLayoutItemViewInfo(inherited ViewInfo);
end;
function TdxLayoutItemPainter.CanDrawBackground: Boolean;
begin
Result := inherited CanDrawBackground and not ViewInfo.IsTransparent;
end;
function TdxLayoutItemPainter.CanDrawCaption: Boolean;
begin
Result := inherited CanDrawCaption or (ViewInfo.IsDragImagePainted and ViewInfo.IsAvailable);
end;
function TdxLayoutItemPainter.CanPaintSpecificPart: Boolean;
begin
Result := CanPaint and not ViewInfo.IsAvailable and ViewInfo.HasControl;
end;
function TdxLayoutItemPainter.GetCaptionPainterClass: TdxCustomLayoutItemCaptionPainterClass;
begin
Result := TdxLayoutItemCaptionPainter;
end;
function TdxLayoutItemPainter.GetControlPainterClass: TdxLayoutItemControlPainterClass;
begin
Result := TdxLayoutItemControlPainter;
end;
procedure TdxLayoutItemPainter.DoDrawControlBorder;
begin
with GetControlPainterClass.Create(Canvas, ViewInfo.ControlViewInfo) do
try
Paint;
finally
Free;
end;
end;
procedure TdxLayoutItemPainter.DoDrawSpecificPart;
function GetControlRect(AControl: TControl): TRect; // copy from cxPC
begin
Result := Rect(0, 0, AControl.Width, AControl.Height);
end;
var
AControl: TWinControl;
begin
Canvas.SaveState;
try
if ViewInfo.Item.Control is TWinControl then
begin
AControl := TWinControl(ViewInfo.Item.Control);
with ViewInfo.Item.Control.BoundsRect.TopLeft do
AControl.PaintTo(Canvas.Canvas, X, Y);
end
else
begin
with ViewInfo.Item.Control.BoundsRect.TopLeft do
MoveWindowOrg(Canvas.Handle, X, Y);
Canvas.IntersectClipRect(GetControlRect(ViewInfo.Item.Control));
ViewInfo.Item.Control.Perform(WM_ERASEBKGND, Canvas.Handle, Canvas.Handle);
ViewInfo.Item.Control.Perform(WM_PAINT, Canvas.Handle, 0);
end;
finally
Canvas.RestoreState;
end;
end;
procedure TdxLayoutItemPainter.DrawContent;
begin
DrawControlBorder;
inherited;
end;
procedure TdxLayoutItemPainter.DrawControlBorder;
begin
if ViewInfo.HasControl then
DoDrawControlBorder;
end;
{ TdxLayoutGroupPainter }
procedure TdxLayoutGroupPainter.PaintSpecificPart;
var
I: Integer;
AViewInfo: TdxCustomLayoutItemViewInfo;
begin
inherited;
for I := 0 to ViewInfo.ItemViewInfoCount - 1 do
begin
AViewInfo := ViewInfo.ItemViewInfos[I];
with AViewInfo.GetPainterClass.Create(Canvas, AViewInfo) do
try
PaintSpecificPart;
finally
Free;
end;
end;
end;
procedure TdxLayoutGroupPainter.PaintDesignFeatures;
var
I: Integer;
AViewInfo: TdxCustomLayoutItemViewInfo;
begin
inherited;
for I := 0 to ViewInfo.ItemViewInfoCount - 1 do
begin
AViewInfo := ViewInfo.ItemViewInfos[I];
with AViewInfo.GetPainterClass.Create(Canvas, AViewInfo) do
try
PaintDesignFeatures;
finally
Free;
end;
end;
end;
function TdxLayoutGroupPainter.GetViewInfo: TdxLayoutGroupViewInfo;
begin
Result := TdxLayoutGroupViewInfo(inherited ViewInfo);
end;
function TdxLayoutGroupPainter.GetCaptionPainterClass: TdxCustomLayoutItemCaptionPainterClass;
begin
Result := TdxLayoutGroupCaptionPainter;
end;
procedure TdxLayoutGroupPainter.DoDrawSpecificPart;
begin
inherited;
ViewInfo.Specific.DrawSpecificPart(Canvas);
end;
procedure TdxLayoutGroupPainter.DoDrawSelectionFrame;
begin
DrawBoundsFrame;
inherited;
end;
procedure TdxLayoutGroupPainter.DoDrawBackground;
begin
inherited;
ViewInfo.Specific.DrawSpecificBackground(Canvas);
end;
procedure TdxLayoutGroupPainter.DrawContent;
begin
DrawBorders;
DrawItemsArea;
inherited;
//DrawBoundsFrame;
end;
procedure TdxLayoutGroupPainter.DoDrawBorders;
//todo: #SC
{var
ASide: TdxLayoutSide;}
begin
//todo: #SC
{with Canvas do
begin
Brush.Color := ViewInfo.Color;
for ASide := Low(TdxLayoutSide) to High(TdxLayoutSide) do
Canvas.FillRect(ViewInfo.BorderRestSpaceBounds[ASide]);
end;}
end;
procedure TdxLayoutGroupPainter.DoDrawRestSpace;
begin
Canvas.Brush.Color := ViewInfo.Color;
Canvas.FillRect(ViewInfo.ClientBounds);
end;
procedure TdxLayoutGroupPainter.DoDrawBoundsFrame;
begin
FrameRectByColor(Canvas.Handle, ViewInfo.SelectionBorderRect, dxLayoutHiddenGroupBorderDefaultColor);
end;
procedure TdxLayoutGroupPainter.DrawBorders;
begin
if ViewInfo.HasBorder and not ViewInfo.IsTransparent then
begin
Canvas.SaveClipRegion;
try
Canvas.ExcludeClipRect(ViewInfo.CaptionViewInfo.Bounds);
DoDrawBorders;
finally
Canvas.RestoreClipRegion;
end;
end;
end;
procedure TdxLayoutGroupPainter.DrawBoundsFrame;
begin
if ViewInfo.HasBoundsFrame then
DoDrawBoundsFrame;
end;
procedure TdxLayoutGroupPainter.DrawItems;
var
I: Integer;
AItemViewInfo: TdxCustomLayoutItemViewInfo;
begin
for I := 0 to ViewInfo.ItemViewInfoCount - 1 do
begin
AItemViewInfo := ViewInfo.ItemViewInfos[I];
if AItemViewInfo.CanPaint then
with AItemViewInfo.GetPainterClass.Create(Canvas, AItemViewInfo) do
try
Paint;
finally
Free;
end;
end;
end;
procedure TdxLayoutGroupPainter.DrawRestSpace;
begin
if not ViewInfo.IsTransparent then
DoDrawRestSpace;
end;
procedure TdxLayoutGroupPainter.DrawItemsArea;
begin
DrawItems;
//todo: #SC DrawRestSpace;
end;
{ TdxLayoutControlPainter }
function TdxLayoutControlPainter.GetInternalCanvas: TcxCanvas;
begin
Result := FControl.Canvas;
end;
procedure TdxLayoutControlPainter.MakeCanvasClipped(ACanvas: TcxCanvas);
begin
ACanvas.IntersectClipRect(ViewInfo.ClientBounds);
end;
procedure TdxLayoutControlPainter.DrawBackground(ACanvas: TcxCanvas);
begin
if not ViewInfo.IsTransparent then
ViewInfo.LayoutLookAndFeel.DrawLayoutControlBackground(ACanvas, ViewInfo.ClientBounds);
end;
procedure TdxLayoutControlPainter.DrawDesignSelector(ACanvas: TcxCanvas);
begin
if Control.IsDesigning and Control.ShowDesignSelectors then
cxDrawDesignRect(ACanvas, Control.GetDesignSelectorRect, Control.IsComponentSelected(Control));
end;
procedure TdxLayoutControlPainter.DrawItems(ACanvas: TcxCanvas);
var
AItemsViewInfo: TdxLayoutGroupViewInfo;
begin
AItemsViewInfo := ViewInfo.ItemsViewInfo;
with AItemsViewInfo.GetPainterClass.Create(ACanvas, AItemsViewInfo) do
try
Paint;
finally
Free;
end;
end;
procedure TdxLayoutControlPainter.DrawDesignFeatures(ACanvas: TcxCanvas);
var
AItemsViewInfo: TdxLayoutGroupViewInfo;
begin
AItemsViewInfo := ViewInfo.ItemsViewInfo;
with AItemsViewInfo.GetPainterClass.Create(ACanvas, AItemsViewInfo) do
try
PaintDesignFeatures;
finally
Free;
end;
end;
procedure TdxLayoutControlPainter.PlaceControls(AItemViewInfo: TdxCustomLayoutItemViewInfo);
var
AControlViewInfos, AWinControlViewInfos: TList;
procedure RetrieveControlViewInfos(AItemViewInfo: TdxCustomLayoutItemViewInfo);
var
I: Integer;
AControlViewInfo: TdxLayoutItemControlViewInfo;
begin
if AItemViewInfo is TdxLayoutGroupViewInfo then
with TdxLayoutGroupViewInfo(AItemViewInfo) do
for I := 0 to ItemViewInfoCount - 1 do
RetrieveControlViewInfos(ItemViewInfos[I])
else
begin
AControlViewInfo := TdxLayoutItemViewInfo(AItemViewInfo).ControlViewInfo;
if AControlViewInfo.Control <> nil then
if AControlViewInfo.Control is TWinControl then
AWinControlViewInfos.Add(AControlViewInfo)
else
AControlViewInfos.Add(AControlViewInfo);
end;
end;
procedure ProcessControls;
var
I: Integer;
begin
for I := 0 to AControlViewInfos.Count - 1 do
with TdxLayoutItemControlViewInfo(AControlViewInfos[I]) do
begin
Control.BoundsRect := ControlBounds;
//ValidateRect(Self.Control.Handle, @ControlBounds);
end;
end;
procedure ProcessWinControls;
var
AWindowsStruct: HDWP;
I: Integer;
AControlViewInfo: TdxLayoutItemControlViewInfo;
R: TRect;
begin
AWindowsStruct := BeginDeferWindowPos(AWinControlViewInfos.Count);
try
for I := 0 to AWinControlViewInfos.Count - 1 do
begin
AControlViewInfo := TdxLayoutItemControlViewInfo(AWinControlViewInfos[I]);
R := AControlViewInfo.ControlBounds;
DeferWindowPos(AWindowsStruct, (AControlViewInfo.Control as TWinControl).Handle, 0,
R.Left, R.Top, cxRectWidth(R), cxRectHeight(R), SWP_NOZORDER or SWP_NOACTIVATE);
end;
finally
EndDeferWindowPos(AWindowsStruct);
end;
end;
function CheckControlSizes(AControlViewInfos: TList): Boolean;
var
I: Integer;
begin
Result := True;
for I := 0 to AControlViewInfos.Count - 1 do
with TdxLayoutItemControlViewInfo(AControlViewInfos[I]) do
begin
Result :=
((ItemViewInfo.AlignHorz = ahClient) or (Control.Width = cxRectWidth(ControlBounds))) and
((ItemViewInfo.AlignVert = avClient) or (Control.Height = cxRectHeight(ControlBounds)));
if not Result then
begin
Item.SaveOriginalControlSize;
Break;
end;
end;
end;
begin
AControlViewInfos := TList.Create;
AWinControlViewInfos := TList.Create;
try
Control.FIsPlacingControls := True;
try
RetrieveControlViewInfos(AItemViewInfo);
ProcessControls;
ProcessWinControls;
finally
Control.FIsPlacingControls := False;
end;
if not CheckControlSizes(AControlViewInfos) or not CheckControlSizes(AWinControlViewInfos) then
Control.LayoutChanged;
finally
AWinControlViewInfos.Free;
AControlViewInfos.Free;
end;
end;
function TdxLayoutControlPainter.GetCanvas: TcxCanvas;
begin
Result := InternalCanvas;
MakeCanvasClipped(Result);
end;
procedure TdxLayoutControlPainter.Paint;
var
ACanvas: TcxCanvas;
begin
ACanvas := GetCanvas;
ACanvas.SaveState;
try
{ moved to TdxLayoutControlViewInfo.Calculate }//PlaceControls; // because of selection drawing
DrawBackground(ACanvas);
DrawItems(ACanvas);
DrawDesignFeatures(ACanvas);
DrawDesignSelector(ACanvas);
// PlaceControls;
finally
ACanvas.RestoreState;
end;
end;
{ THitTests }
type
THitTests = class
private
FItems: TList;
function GetCount: Integer;
function GetInstance(AClass: TdxCustomLayoutHitTestClass): TdxCustomLayoutHitTest;
function GetItem(Index: Integer): TdxCustomLayoutHitTest;
protected
function GetObjectByClass(AClass: TdxCustomLayoutHitTestClass): TdxCustomLayoutHitTest;
property Count: Integer read GetCount;
property Items[Index: Integer]: TdxCustomLayoutHitTest read GetItem;
public
constructor Create;
destructor Destroy; override;
property Instances[AClass: TdxCustomLayoutHitTestClass]: TdxCustomLayoutHitTest read GetInstance; default;
end;
var
HitTests: THitTests;
constructor THitTests.Create;
begin
inherited;
FItems := TList.Create;
end;
destructor THitTests.Destroy;
var
I: Integer;
begin
for I := 0 to Count - 1 do
Items[I].Free;
FItems.Free;
inherited;
end;
function THitTests.GetCount: Integer;
begin
Result := FItems.Count;
end;
function THitTests.GetInstance(AClass: TdxCustomLayoutHitTestClass): TdxCustomLayoutHitTest;
begin
Result := GetObjectByClass(AClass);
if Result = nil then
begin
Result := AClass.Create;
FItems.Add(Result);
end;
end;
function THitTests.GetItem(Index: Integer): TdxCustomLayoutHitTest;
begin
Result := FItems[Index];
end;
function THitTests.GetObjectByClass(AClass: TdxCustomLayoutHitTestClass): TdxCustomLayoutHitTest;
var
I: Integer;
begin
for I := 0 to Count - 1 do
begin
Result := Items[I];
if Result.ClassType = AClass then Exit;
end;
Result := nil;
end;
{ TdxCustomLayoutHitTest }
function TdxCustomLayoutHitTest.Cursor: TCursor;
begin
Result := crDefault;
end;
class function TdxCustomLayoutHitTest.HitTestCode: Integer;
begin
Result := htError;
end;
class function TdxCustomLayoutHitTest.Instance: TdxCustomLayoutHitTest;
begin
Result := HitTests.Instances[Self];
end;
function TdxCustomLayoutHitTest.GetGroupForInsert: TdxLayoutGroup;
begin
Result := nil;
end;
{ TdxLayoutNoneHitTest }
class function TdxLayoutNoneHitTest.HitTestCode: Integer;
begin
Result := htNone;
end;
{ TdxLayoutItemHitTest }
function TdxLayoutItemHitTest.GetItem: TdxLayoutItem;
begin
Result := TdxLayoutItem(inherited Item);
end;
procedure TdxLayoutItemHitTest.SetItem(Value: TdxLayoutItem);
begin
inherited Item := Value;
end;
class function TdxLayoutItemHitTest.HitTestCode: Integer;
begin
Result := htItem;
end;
function TdxLayoutItemHitTest.GetGroupForInsert: TdxLayoutGroup;
begin
Result := Item.Parent;
end;
{ TdxLayoutGroupHitTest }
function TdxLayoutGroupHitTest.GetItem: TdxLayoutGroup;
begin
Result := TdxLayoutGroup(inherited Item);
end;
procedure TdxLayoutGroupHitTest.SetItem(Value: TdxLayoutGroup);
begin
inherited Item := Value;
end;
class function TdxLayoutGroupHitTest.HitTestCode: Integer;
begin
Result := htGroup;
end;
function TdxLayoutGroupHitTest.GetGroupForInsert: TdxLayoutGroup;
begin
Result := Item;
end;
{ TdxLayoutCustomizeFormHitTest }
class function TdxLayoutCustomizeFormHitTest.HitTestCode: Integer;
begin
Result := htCustomizeForm;
end;
{ TdxLayoutCustomizeFormAvailableItemsHitTest }
class function TdxLayoutCustomizeFormAvailableItemsHitTest.HitTestCode: Integer;
begin
Result := htAvailableItems;
end;
{ TdxLayoutCustomizeFormTreeViewItemsHitTest }
class function TdxLayoutCustomizeFormTreeViewItemsHitTest.HitTestCode: Integer;
begin
Result := htTreeViewItems;
end;
{ TdxLayoutClientAreaHitTest }
class function TdxLayoutClientAreaHitTest.HitTestCode: Integer;
begin
Result := htClientArea;
end;
{ TdxLayoutGroup }
constructor TdxLayoutGroup.Create(AOwner: TComponent);
begin
inherited;
FIsUserDefined := True;
FItems := TcxComponentList.Create(True);
FItems.OnComponentListChanged := ItemListChanged;
FVisibleItems := TcxComponentList.Create;
FLayoutDirection := ldVertical;
FShowBorder := True;
FUseIndent := True;
end;
destructor TdxLayoutGroup.Destroy;
var
ANeedCreateNewRootGroup: Boolean;
begin
ANeedCreateNewRootGroup := IsRoot and not (csReading in Container.ComponentState) and
not Container.IsDestroying;
if ANeedCreateNewRootGroup then
Container.CreateRootGroup;
FreeAndNil(FVisibleItems);
FreeAndNil(FItems);
if ANeedCreateNewRootGroup then
Container.LayoutChanged;
inherited;
end;
function TdxLayoutGroup.GetCount: Integer;
begin
Result := FItems.Count;
end;
function TdxLayoutGroup.GetItem(Index: Integer): TdxCustomLayoutItem;
begin
Result := TdxCustomLayoutItem(FItems[Index]);
end;
function TdxLayoutGroup.GetShowBorder: Boolean;
begin
Result := not FHidden and FShowBorder;
end;
function TdxLayoutGroup.GetViewInfo: TdxLayoutGroupViewInfo;
begin
Result := TdxLayoutGroupViewInfo(inherited ViewInfo);
end;
function TdxLayoutGroup.GetVisibleCount: Integer;
begin
Result := FVisibleItems.Count;
end;
function TdxLayoutGroup.GetVisibleItem(Index: Integer): TdxCustomLayoutItem;
begin
Result := TdxCustomLayoutItem(FVisibleItems[Index]);
end;
procedure TdxLayoutGroup.SetItemIndex(Value: Integer);
begin
if not IsLoading and (Value > VisibleCount) then
Value := -1;
if FItemIndex <> Value then
begin
FItemIndex := Value;
Changed(ictMedium);
end;
end;
procedure TdxLayoutGroup.SetHidden(Value: Boolean);
begin
if FHidden <> Value then
begin
FHidden := Value;
if not IsRoot then
Changed;
end;
end;
procedure TdxLayoutGroup.SetLayoutDirection(Value: TdxLayoutDirection);
begin
if FLayoutDirection <> Value then
begin
FLayoutDirection := Value;
Changed;
end;
end;
procedure TdxLayoutGroup.SetLocked(Value: Boolean);
begin
if FLocked <> Value then
begin
FLocked := Value;
end;
end;
procedure TdxLayoutGroup.SetLayoutLookAndFeelException(Value: Boolean);
begin
if FLayoutLookAndFeelException <> Value then
begin
FLayoutLookAndFeelException := Value;
LayoutLookAndFeelUserChanged;
end;
end;
procedure TdxLayoutGroup.SetShowBorder(Value: Boolean);
begin
if FShowBorder <> Value then
begin
FShowBorder := Value;
Changed;
end;
end;
procedure TdxLayoutGroup.SetUseIndent(Value: Boolean);
begin
if FUseIndent <> Value then
begin
FUseIndent := Value;
Changed;
end;
end;
procedure TdxLayoutGroup.AddItem(AItem: TdxCustomLayoutItem);
begin
FItems.Add(AItem);
AItem.FParent := Self;
AItem.Container := FContainer;
if not IsLoading then
AItem.Init;
end;
procedure TdxLayoutGroup.ExtractItem(AItem: TdxCustomLayoutItem);
begin
if not (csDestroying in ComponentState) then
begin
FItems.Extract(AItem);
AItem.FParent := nil;
Changed;
end;
end;
procedure TdxLayoutGroup.ItemListChanged(Sender: TObject; AComponent: TComponent; AAction: TcxComponentCollectionNotification);
begin
if IsLoading then
Exit;
BuildVisibleItemsList;
if ItemIndex > VisibleCount - 1 then
ItemIndex := VisibleCount - 1
else
if (ItemIndex = -1) and (VisibleCount > 0) then
ItemIndex := 0;
Changed;
end;
function TdxLayoutGroup.IsChildActuallyVisible(AChild: TdxCustomLayoutItem): Boolean;
begin
Result := ActuallyVisible and AllowDrawChild(AChild);
end;
function TdxLayoutGroup.GetChildLayoutLookAndFeel: TdxCustomLayoutLookAndFeel;
begin
if LayoutLookAndFeelException and (Parent <> nil) then
Result := Parent.GetChildLayoutLookAndFeel
else
Result := GetLayoutLookAndFeel;
end;
function TdxLayoutGroup.CanDelete: Boolean;
var
I: Integer;
begin
Result := not IsRoot and inherited CanDelete;
if Result then
for I := 0 to Count - 1 do
begin
Result := Items[I].CanDelete;
if not Result then
Break;
end;
end;
function TdxLayoutGroup.CanProcessAccel(out AItem: TdxCustomLayoutItem): Boolean;
var
I: Integer;
begin
Result := False;
for I := 0 to VisibleCount - 1 do
begin
AItem := VisibleItems[I];
Result := AItem.CanProcessAccel(AItem);
if Result then Break;
end;
end;
function TdxLayoutGroup.CanRemove: Boolean;
var
I: Integer;
begin
Result := inherited CanRemove;
if Result then
for I := 0 to Count - 1 do
begin
Result := Items[I].CanRemove;
if not Result then Break;
end;
end;
procedure TdxLayoutGroup.ContainerChanged;
var
I: Integer;
begin
for I := 0 to Count - 1 do
Items[I].Container := Container;
end;
procedure TdxLayoutGroup.DoPack;
var
I: Integer;
ASomethingDone: Boolean;
AGroup: TdxLayoutGroup;
begin
for I := Count - 1 downto 0 do
Items[I].Pack;
repeat
ASomethingDone := False;
if (Count = 0) and CanDestroy then
begin
Free;
Exit;
end;
if Count = 1 then
begin
if Items[0] is TdxLayoutGroup then
begin
AGroup := TdxLayoutGroup(Items[0]);
if AGroup.CanDestroy then
begin
LayoutDirection := AGroup.LayoutDirection;
AGroup.MoveChildrenToParent;
AGroup.Free;
ASomethingDone := True;
end;
end;
if not ASomethingDone and CanDestroy then
begin
Items[0].Move(Parent, Index);
ASomethingDone := True;
end;
end;
until not ASomethingDone;
end;
procedure TdxLayoutGroup.EnabledChanged;
var
I: Integer;
begin
for I := 0 to Count - 1 do
Items[I].EnabledChanged;
inherited;
end;
function TdxLayoutGroup.GetBaseName: string;
begin
Result := inherited GetBaseName + 'Group';
end;
procedure TdxLayoutGroup.GetChildren(Proc: TGetChildProc; Root: TComponent);
var
I: Integer;
begin
inherited;
for I := 0 to Count - 1 do
if Items[I].Owner = Root then
Proc(Items[I]);
end;
function TdxLayoutGroup.GetShowCaption: Boolean;
begin
Result := {#DG ShowBorder and }inherited GetShowCaption;
end;
function TdxLayoutGroup.GetViewInfoClass: TdxCustomLayoutItemViewInfoClass;
begin
Result := TdxCustomLayoutItemViewInfoClass(GetLayoutLookAndFeel.GetGroupViewInfoClass);
end;
procedure TdxLayoutGroup.Loaded;
begin
inherited;
FIsUserDefined := False;
end;
procedure TdxLayoutGroup.LayoutLookAndFeelChanged;
var
I: Integer;
begin
inherited;
for I := 0 to VisibleCount - 1 do
VisibleItems[I].LayoutLookAndFeelChanged;
end;
procedure TdxLayoutGroup.LayoutLookAndFeelChanging;
var
I: Integer;
begin
inherited;
for I := 0 to VisibleCount - 1 do
VisibleItems[I].LayoutLookAndFeelChanging;
end;
function TdxLayoutGroup.ProcessDialogChar(ACharCode: Word): Boolean;
var
I: Integer;
begin
Result := inherited ProcessDialogChar(ACharCode);
if not Result then
for I := 0 to VisibleCount - 1 do
begin
Result := VisibleItems[I].ProcessDialogChar(ACharCode);
if Result then Break;
end;
end;
procedure TdxLayoutGroup.RestoreItemControlSize;
var
I: Integer;
begin
for I := 0 to Count - 1 do
Items[I].RestoreItemControlSize;
end;
procedure TdxLayoutGroup.SetChildOrder(Child: TComponent; Order: Integer);
begin
inherited;
(Child as TdxCustomLayoutItem).Index := Order;
end;
procedure TdxLayoutGroup.SetParentComponent(Value: TComponent);
begin
//#DG
if Value is TdxCustomLayoutControl and
not TdxCustomLayoutControl(Value).Items.IsLoading and
not (csAncestor in ComponentState) then
TdxCustomLayoutControl(Value).SetRootGroup(Self)
else
inherited;
end;
procedure TdxLayoutGroup.BeforeCalculateViewInfo;
var
I: Integer;
begin
BuildVisibleItemsList;
for I := 0 to Count - 1 do
Items[I].BeforeCalculateViewInfo;
end;
procedure TdxLayoutGroup.AfterCalculateViewInfo;
var
I: Integer;
begin
if ViewInfo <> nil then
ViewInfo.Specific.SetControlVisibility;
for I := 0 to Count - 1 do
Items[I].AfterCalculateViewInfo;
inherited;
end;
function TdxLayoutGroup.CanDestroy: Boolean;
begin
Result := Hidden and not IsRoot and not Locked;
end;
procedure TdxLayoutGroup.BuildVisibleItemsList;
var
I: Integer;
begin
FVisibleItems.Clear;
for I := 0 to Count - 1 do
if Items[I].GetVisible then
FVisibleItems.Add(Items[I]);
end;
function TdxLayoutGroup.GetHelperClass: TdxLayoutGroupHelperClass;
begin
case LayoutDirection of
ldHorizontal: Result := TdxLayoutHorizontalGroupHelper;
ldVertical: Result := TdxLayoutVerticalGroupHelper;
ldTabbed: Result := TdxLayoutTabbedGroupHelper;
else
raise EdxException.Create('TdxLayoutGroup.GetHelperClass fails');
end;
end;
function TdxLayoutGroup.AllowDrawChild(AChild: TdxCustomLayoutItem): Boolean;
begin
Result := (ViewInfo = nil) or ViewInfo.Specific.AllowDrawChild(AChild);
end;
procedure TdxLayoutGroup.ChangeItemIndex(AItem: TdxCustomLayoutItem;
Value: Integer);
begin
if AItem.Index <> Value then
begin
FItems.Move(AItem.Index, Value);
if AItem.GetVisible then
begin
BuildVisibleItemsList;
Changed;
end;
end;
end;
procedure TdxLayoutGroup.ChangeItemVisibleIndex(AItem: TdxCustomLayoutItem;
Value: Integer);
begin
ChangeItemIndex(AItem, GetItemIndex(Value));
end;
function TdxLayoutGroup.GetItemIndex(AItemVisibleIndex: Integer): Integer;
begin
if (0 <= AItemVisibleIndex) and (AItemVisibleIndex < VisibleCount) then
Result := VisibleItems[AItemVisibleIndex].Index
else
Result := Count;
end;
function TdxLayoutGroup.IndexOf(AItem: TdxCustomLayoutItem): Integer;
begin
Result := FItems.IndexOf(AItem);
end;
function TdxLayoutGroup.VisibleIndexOf(AItem: TdxCustomLayoutItem): Integer;
begin
Result := FVisibleItems.IndexOf(AItem);
end;
function TdxLayoutGroup.CreateGroup(AGroupClass: TdxLayoutGroupClass = nil): TdxLayoutGroup;
begin
Result := Container.CreateGroup(AGroupClass, Self);
end;
function TdxLayoutGroup.CreateItem(AItemClass: TdxCustomLayoutItemClass = nil): TdxCustomLayoutItem;
begin
Result := Container.CreateItem(AItemClass, Self);
end;
function TdxLayoutGroup.CreateItemForControl(AControl: TControl): TdxLayoutItem;
begin
Result := Container.CreateItemForControl(AControl, Self);
end;
function TdxLayoutGroup.CanMoveTo(AParent: TdxCustomLayoutItem): Boolean;
begin
Result := (AParent = nil) or inherited CanMoveTo(AParent) and not IsChildItem(AParent);
end;
procedure TdxLayoutGroup.MoveChildrenToParent;
var
AInsertionIndex, I: Integer;
begin
AInsertionIndex := Index;
for I := Count - 1 downto 0 do
Items[I].Move(Parent, AInsertionIndex);
end;
function TdxLayoutGroup.PutChildrenIntoHiddenGroup: TdxLayoutGroup;
var
I: Integer;
begin
Result := CreateGroup;
Result.Hidden := True;
Result.LayoutDirection := LayoutDirection;
for I := Count - 2 downto 0 do
Items[I].Move(Result, 0);
end;
{ TdxLayoutItem }
constructor TdxLayoutItem.Create(AOwner: TComponent);
begin
inherited;
FControlOptions := GetControlOptionsClass.Create(Self);
end;
destructor TdxLayoutItem.Destroy;
begin
Control := nil;
FControlOptions.Free;
inherited;
end;
function TdxLayoutItem.GetCaptionOptions: TdxLayoutItemCaptionOptions;
begin
Result := TdxLayoutItemCaptionOptions(inherited CaptionOptions);
end;
function TdxLayoutItem.GetViewInfo: TdxLayoutItemViewInfo;
begin
Result := TdxLayoutItemViewInfo(inherited ViewInfo);
end;
procedure TdxLayoutItem.SetCaptionOptions(Value: TdxLayoutItemCaptionOptions);
begin
inherited CaptionOptions := Value;
end;
procedure TdxLayoutItem.SetControl(Value: TControl);
procedure CheckValue;
var
AItem: TdxLayoutItem;
begin
if Value <> nil then
begin
if Value = Container then
raise EdxException.Create(sdxLayoutControlContainerCannotBeControl);
AItem := FContainer.FindItem(Value);
if AItem <> nil then
raise EdxException.Create(Format(sdxLayoutControlControlIsUsed, [Value.Name, AItem.Name]))
end;
end;
procedure UnprepareControl;
begin
Control.RemoveFreeNotification(Self);
if IsDesigning then
with Control do
ControlStyle := ControlStyle - [csNoDesignVisible];
FreeAndNil(FDesignSelectorControls);
Control.WindowProc := FDefaultControlWndProc;
FDefaultControlWndProc := nil;
FreeAndNil(FControlAdapter);
if IsDesigning and not (csDestroying in Control.ComponentState) then
begin
Control.Left := 0;
Control.Top := 0;
end;
end;
procedure PrepareControl;
var
ASelectorItem: TdxControlDesignSelectorItem;
begin
FDefaultControlWndProc := Control.WindowProc;
Control.WindowProc := ControlWndProc;
if IsDesigning then
begin
FDesignSelectorControls := TdxSatelliteControls.Create(True);
ASelectorItem := TdxControlDesignSelectorItem(TdxSatelliteControls(FDesignSelectorControls).AddControl(TWinControl(Control), TdxControlDesignSelectorItem));
ASelectorItem.LayoutItem := Self;
end;
Control.FreeNotification(Self);
if IsDesigning then
with FControl do
ControlStyle := ControlStyle + [csNoDesignVisible];
Control.Parent := Container;
SaveOriginalControlSize;
CreateControlAdapter;
SaveOriginalControlSize;
if HasWinControl and not TWinControl(Control).HandleAllocated then
SaveControlSizeBeforeDestruction;
end;
begin
if FControl <> Value then
begin
CheckValue;
FControlLocked := True;
try
if FControl <> nil then
UnprepareControl;
FControl := Value;
if Value <> nil then
PrepareControl;
finally
FControlLocked := False;
end;
Changed;
if Container.Customization then
Container.UpdateCustomizationControls;
end;
end;
function TdxLayoutItem.CanFocusControlOnCaptionClick: Boolean;
begin
Result := not Container.IsCustomization and Container.FocusControlOnItemCaptionClick and CanFocusControl;
end;
procedure TdxLayoutItem.CreateControlAdapter;
begin
FControlAdapter :=
dxLayoutControlAdapterDefs.GetAdapterClass(FControl).Create(Self);
end;
{procedure TdxLayoutItem.PostFree;
begin
Container.PostFree(Self);
end;}
function TdxLayoutItem.CanDelete: Boolean;
begin
Result := inherited CanDelete and (IsDesigning or not HasControl);
end;
function TdxLayoutItem.CanFocusOnClick(X, Y: Integer): Boolean;
begin
Result := CanFocusControlOnCaptionClick and ViewInfo.CaptionViewInfo.CanDoCaptionClick(X, Y);
end;
function TdxLayoutItem.CanProcessAccel(out AItem: TdxCustomLayoutItem): Boolean;
begin
Result := CanFocusControl and CanTabStopControl;
if Result then
AItem := Self;
end;
procedure TdxLayoutItem.ContainerChanged;
procedure ResetControlParent;
var
ASavedControl: TControl;
begin
if Control.Parent <> Container then
begin
ASavedControl := Control;
Control := nil;
Control := ASavedControl;
end;
end;
begin
if HasControl and (Container <> nil) then
ResetControlParent;
end;
procedure TdxLayoutItem.DoCaptionDown;
begin
if CanFocusControlOnCaptionClick then
SetControlFocus;
end;
procedure TdxLayoutItem.EnabledChanged;
begin
inherited;
SetControlEnablement;
end;
function TdxLayoutItem.GetParentManagedAlignVert: TdxLayoutAlignVert;
begin
Result := avTop;
end;
function TdxLayoutItem.GetBaseName: string;
begin
Result := inherited GetBaseName + 'Item';
end;
function TdxLayoutItem.GetViewInfoClass: TdxCustomLayoutItemViewInfoClass;
begin
Result := TdxCustomLayoutItemViewInfoClass(GetLayoutLookAndFeel.GetItemViewInfoClass);
end;
procedure TdxLayoutItem.Init;
var
ACommonValue: Variant;
function IsCommonValue(AValueIndex: Integer; var ACommonValue: Variant): Boolean;
var
I: Integer;
AValue: Variant;
function CheckValue(AItem: TdxCustomLayoutItem): Boolean;
begin
if AItem <> Self then
case AValueIndex of
0..2: Result := AItem is TdxLayoutItem;
// 3..4: Result := True;
else
Result := False;
end
else
Result := False;
end;
function GetValue(AItem: TdxCustomLayoutItem): Variant;
begin
case AValueIndex of
0: Result := TdxLayoutItem(AItem).CaptionOptions.Layout;
1: Result := TdxLayoutItem(AItem).CaptionOptions.AlignHorz;
2: Result := TdxLayoutItem(AItem).CaptionOptions.AlignVert;
// 3: Result := AItem.AlignHorz;
// 4: Result := AItem.AlignVert;
else
Result := Null;
end;
end;
begin
Result := Parent <> nil;
if not Result then Exit;
Result := False;
ACommonValue := Unassigned;
for I := 0 to Parent.VisibleCount - 1 do
if CheckValue(Parent.VisibleItems[I]) then
begin
AValue := GetValue(Parent.VisibleItems[I]);
if VarIsEmpty(ACommonValue) then
ACommonValue := AValue;
Result := AValue = ACommonValue;
if not Result then Break;
end;
end;
begin
inherited;
if IsCommonValue(0, ACommonValue) then
CaptionOptions.Layout := ACommonValue;
if IsCommonValue(1, ACommonValue) then
CaptionOptions.AlignHorz := ACommonValue;
if IsCommonValue(2, ACommonValue) then
CaptionOptions.AlignVert := ACommonValue;
{if IsCommonValue(3, ACommonValue) then
AlignHorz := ACommonValue; - items lose client alignment}
{if IsCommonValue(4, ACommonValue) then
AlignVert := ACommonValue; - because some controls cannot be made client aligned }
end;
procedure TdxLayoutItem.Loaded;
begin
inherited;
if HasControl then
SaveOriginalControlSize;
end;
procedure TdxLayoutItem.LayoutLookAndFeelChanged;
begin
inherited;
if FControlAdapter <> nil then
FControlAdapter.LayoutLookAndFeelChanged;
end;
procedure TdxLayoutItem.UpdateDesignSelectors;
var
AIndex: Integer;
R: TRect;
AItem: TdxControlDesignSelectorItem;
begin
if HasControl and (FDesignSelectorControls <> nil) then
begin
AIndex := TdxSatelliteControls(FDesignSelectorControls).FindByControl(Control);
if AIndex <> -1 then
begin
AItem := TdxSatelliteControls(FDesignSelectorControls).Items[AIndex] as TdxControlDesignSelectorItem;
R := ViewInfo.DesignSelectorRect;
R := cxRectOffset(R, ViewInfo.ControlViewInfo.Bounds.TopLeft, False);
AItem.SelectorBounds := R;
end;
end;
end;
procedure TdxLayoutItem.Notification(AComponent: TComponent; Operation: TOperation);
begin
inherited;
if (Operation = opRemove) and (AComponent = FControl) then
begin
Control := nil;
Free; // #DG
// #DG PostFree;
end;
end;
procedure TdxLayoutItem.ProcessAccel;
begin
SetControlFocus;
end;
procedure TdxLayoutItem.RestoreItemControlSize;
begin
if HasControl then
Control.SetBounds(Control.Left, Control.Top, FOriginalControlSize.X, FOriginalControlSize.Y);
end;
procedure TdxLayoutItem.CustomizationMouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
if Container.ShowDesignSelectors and IsDesigning and Container.Customization and HasControl and PtInRect(ViewInfo.DesignSelectorRect, Point(X, Y)) then
Container.SelectComponent(Control, Shift)
else
inherited CustomizationMouseDown(Button, Shift, X, Y);
end;
procedure TdxLayoutItem.AfterCalculateViewInfo;
begin
SetControlVisibility;
SetControlEnablement;
inherited;
end;
function TdxLayoutItem.GetCaptionOptionsClass: TdxCustomLayoutItemCaptionOptionsClass;
begin
Result := TdxLayoutItemCaptionOptions;
end;
function TdxLayoutItem.GetControlOptionsClass: TdxLayoutItemControlOptionsClass;
begin
Result := TdxLayoutItemControlOptions;
end;
function TdxLayoutItem.CanFocusControl: Boolean;
begin
Result := HasWinControl and TWinControl(Control).CanFocus;
end;
function TdxLayoutItem.CanTabStopControl: Boolean;
begin
Result := HasWinControl and TWinControl(Control).TabStop;
end;
procedure TdxLayoutItem.ControlWndProc(var Message: TMessage);
function IsControlMoved: Boolean;
begin
Result := (Message.LParam = 0) or (PWindowPos(Message.LParam)^.flags and SWP_NOMOVE = 0);
end;
function IsControlResized: Boolean;
begin
Result := (Message.LParam = 0) or (PWindowPos(Message.LParam)^.flags and SWP_NOSIZE = 0);
end;
function ControlSizeChanged: Boolean;
begin
Result := not cxPointIsEqual(Point(Control.Width, Control.Height), FOriginalControlSize);
end;
var
ANeedProcessDefaultControlWndProc: Boolean;
begin
ANeedProcessDefaultControlWndProc := True;
case Message.Msg of
WM_NCHITTEST:
if Container.Customization then
begin
Message.Result := HTTRANSPARENT;
ANeedProcessDefaultControlWndProc := False;
end;
end;
if ANeedProcessDefaultControlWndProc then
FDefaultControlWndProc(Message);
if not FControlLocked then
with Message do
case Msg of
WM_CREATE:
if (Control.Width <> ControlSizeBeforeDestruction.X) or
(Control.Height <> ControlSizeBeforeDestruction.Y) then
begin
SaveOriginalControlSize;
Changed;
end;
WM_DESTROY:
SaveControlSizeBeforeDestruction;
WM_SETFOCUS:
MakeVisible;
WM_WINDOWPOSCHANGED:
if not Container.IsPlacingControls and (IsControlMoved or IsControlResized) then
begin
if IsControlResized and FControlAdapter.AllowCheckSize and ControlSizeChanged then
SaveOriginalControlSize;
Changed;
end;
CM_TABSTOPCHANGED:
Container.ViewInfo.DoCalculateTabOrders;
end;
end;
function TdxLayoutItem.HasControl: Boolean;
begin
Result := FControl <> nil;
end;
function TdxLayoutItem.HasWinControl: Boolean;
begin
Result := HasControl and (FControl is TWinControl);
end;
procedure TdxLayoutItem.SaveControlSizeBeforeDestruction;
begin
FControlSizeBeforeDestruction := Point(Control.Width, Control.Height);
end;
procedure TdxLayoutItem.SaveOriginalControlSize;
begin
if HasWinControl and CanAllocateHandle(TWinControl(FControl)) then
TWinControl(FControl).HandleNeeded; // for cxEditors
FOriginalControlSize := Point(FControl.Width, FControl.Height);
end;
procedure TdxLayoutItem.SetControlEnablement;
begin
if HasControl then
Control.Enabled := EnabledForWork;
end;
procedure TdxLayoutItem.SetControlFocus;
begin
TWinControl(FControl).SetFocus;
end;
procedure TdxLayoutItem.SetControlVisibility;
begin
if HasControl then
begin
Control.Visible := ActuallyVisible and ViewInfo.ActuallyVisible;
// to make the control invisible on showing
if not Control.Visible then
Control.SetBounds(10000, 10000, FOriginalControlSize.X, FOriginalControlSize.Y);
end;
end;
{ TdxLayoutControlViewInfo }
constructor TdxLayoutControlViewInfo.Create(AControl: TdxCustomLayoutControl);
begin
inherited;
CreateViewInfos;
end;
destructor TdxLayoutControlViewInfo.Destroy;
begin
DestroyViewInfos;
FCanvas.Free;
FreeAndNil(FSelectionLayer);
inherited;
end;
procedure TdxLayoutControlViewInfo.CreateSelectionLayer;
begin
FSelectionLayer := TdxSelectionLayer.Create(Control, Control.Handle);
end;
procedure TdxLayoutControlViewInfo.BuildSelectionLayer;
function CanBuildSelectionLayer: Boolean;
var
I: Integer;
AList: TcxObjectList;
AIntf: IdxLayoutSelectableItem;
begin
Result := (Control.IsDesigning or Control.Customization) and not Control.IsUpdateLocked;
if Result then
begin
Result := False;
AList := TcxObjectList.Create(False);
try
Control.GetSelection(AList);
for I := 0 to AList.Count - 1 do
begin
if Supports(AList[I], IdxLayoutSelectableItem, AIntf) and AIntf.IsChild(Control) and AIntf.IsVisible then
begin
Result := True;
AIntf := nil;
Break;
end;
end;
finally
AList.Free;
end;
end;
end;
begin
if CanBuildSelectionLayer then
begin
SelectionLayer.BoundsRect := ClientBounds;
SelectionLayer.SelectionImage.Clear;
ItemsViewInfo.PaintSelectionLayer;
SelectionLayer.SelectionImage.RecoverAlphaChannel(0);
SelectionLayer.Show;
end
else
FreeAndNil(FSelectionLayer);
end;
function TdxLayoutControlViewInfo.GetClientHeight: Integer;
begin
Result := cxRectHeight(ClientBounds);
end;
function TdxLayoutControlViewInfo.GetClientWidth: Integer;
begin
Result := cxRectWidth(ClientBounds);
end;
function TdxLayoutControlViewInfo.GetContentHeight: Integer;
begin
Result := cxRectHeight(ContentBounds);
end;
function TdxLayoutControlViewInfo.GetContentWidth: Integer;
begin
Result := cxRectWidth(ContentBounds);
end;
function TdxLayoutControlViewInfo.GetLayoutLookAndFeel: TdxCustomLayoutLookAndFeel;
begin
Result := FControl.GetLayoutLookAndFeel;
end;
function TdxLayoutControlViewInfo.GetSelectionLayer: TdxSelectionLayer;
begin
if FSelectionLayer = nil then
CreateSelectionLayer;
Result := FSelectionLayer;
end;
procedure TdxLayoutControlViewInfo.CreateViewInfos;
begin
if LayoutLookAndFeel <> nil then
FItemsViewInfo := GetItemsViewInfoClass.Create(Self, nil, FControl.Items);
end;
procedure TdxLayoutControlViewInfo.DestroyViewInfos;
begin
FreeAndNil(FItemsViewInfo);
end;
function TdxLayoutControlViewInfo.GetItemsViewInfoClass: TdxLayoutGroupViewInfoClass;
begin
Result := TdxLayoutGroupViewInfoClass(FControl.Items.GetViewInfoClass);
end;
procedure TdxLayoutControlViewInfo.RecreateViewInfos;
begin
DestroyViewInfos;
CreateViewInfos;
end;
procedure TdxLayoutControlViewInfo.AlignItems;
var
I: Integer;
procedure ProcessConstraint(AConstraint: TdxLayoutAlignmentConstraint);
var
AItemViewInfos: TList;
procedure RetrieveItemViewInfos;
var
I: Integer;
AViewInfo: TdxCustomLayoutItemViewInfo;
begin
for I := 0 to AConstraint.Count - 1 do
begin
AViewInfo := AConstraint.Items[I].ViewInfo;
if AViewInfo <> nil then
AItemViewInfos.Add(AViewInfo);
end;
end;
function GetSide: TdxLayoutSide;
begin
if AConstraint.Kind in [ackLeft, ackRight] then
Result := sdLeft
else
Result := sdTop;
end;
function AlignItemViewInfos: Boolean;
var
AMaxBorderValue, I: Integer;
function GetBorderValue(AItemViewInfoIndex: Integer): Integer;
begin
with TdxCustomLayoutItemViewInfo(AItemViewInfos[AItemViewInfoIndex]) do
case AConstraint.Kind of
ackLeft:
Result := Bounds.Left - CalculateOffset(sdLeft);
ackTop:
Result := Bounds.Top - CalculateOffset(sdTop);
ackRight:
Result := Bounds.Right + CalculateOffset(sdRight);
ackBottom:
Result := Bounds.Bottom + CalculateOffset(sdBottom);
else
Result := 0;
end;
end;
function FindMaxBorderValue: Integer;
var
I: Integer;
begin
Result := -MaxInt;
for I := 0 to AItemViewInfos.Count - 1 do
Result := Max(Result, GetBorderValue(I));
end;
procedure ChangeOffset(AItemViewInfoIndex, ADelta: Integer);
begin
with TdxCustomLayoutItemViewInfo(AItemViewInfos[AItemViewInfoIndex]) do
Offsets[GetSide] := Offsets[GetSide] + ADelta;
end;
function AreItemViewInfosAligned: Boolean;
var
I, ABorderValue: Integer;
begin
ABorderValue := 0;
for I := 0 to AItemViewInfos.Count - 1 do
if I = 0 then
ABorderValue := GetBorderValue(I)
else
begin
Result := GetBorderValue(I) = ABorderValue;
if not Result then Exit;
end;
Result := True;
end;
begin
AMaxBorderValue := FindMaxBorderValue;
for I := 0 to AItemViewInfos.Count - 1 do
ChangeOffset(I, AMaxBorderValue - GetBorderValue(I));
CalculateItemsViewInfo;
Result := AreItemViewInfosAligned;
end;
procedure ResetOffsets;
var
I: Integer;
begin
for I := 0 to AItemViewInfos.Count - 1 do
TdxCustomLayoutItemViewInfo(AItemViewInfos[I]).ResetOffset(GetSide);
CalculateItemsViewInfo;
end;
begin
AItemViewInfos := TList.Create;
try
RetrieveItemViewInfos;
while not AlignItemViewInfos do //!!! to think about invisible items if items will be deleted
begin
ResetOffsets;
if AItemViewInfos.Count > 2 then
AItemViewInfos.Count := AItemViewInfos.Count - 1
else
Break;
end;
finally
AItemViewInfos.Free;
end;
end;
begin
for I := 0 to FControl.AlignmentConstraintCount - 1 do
ProcessConstraint(FControl.AlignmentConstraints[I]);
end;
function CompareAllItemViewInfos(Item1, Item2: TdxLayoutItemViewInfo): Integer;
begin
Result := Ord(Item2.CaptionLayout) - Ord(Item1.CaptionLayout);
end;
function CompareItemViewInfos(Item1, Item2: TdxLayoutItemViewInfo): Integer;
begin
case Item1.CaptionLayout of
clLeft:
Result := Item1.Bounds.Left - Item2.Bounds.Left;
clTop:
Result := Item1.Bounds.Top - Item2.Bounds.Top;
clRight:
Result := Item1.Bounds.Right - Item2.Bounds.Right;
clBottom:
Result := Item1.Bounds.Bottom - Item2.Bounds.Bottom;
else
Result := 0;
end;
end;
procedure TdxLayoutControlViewInfo.AutoAlignControls;
var
AAllItemViewInfos: TList;
ACaptionLayout: TdxCaptionLayout;
procedure FindAllItemViewInfos(ACustomItemViewInfo: TdxCustomLayoutItemViewInfo);
var
I: Integer;
begin
if ACustomItemViewInfo is TdxLayoutGroupViewInfo then
with TdxLayoutGroupViewInfo(ACustomItemViewInfo) do
for I := 0 to ItemViewInfoCount - 1 do
FindAllItemViewInfos(ItemViewInfos[I])
else
if TdxLayoutItemViewInfo(ACustomItemViewInfo).AutoControlAlignment then
AAllItemViewInfos.Add(ACustomItemViewInfo);
end;
procedure SortAllItemViewInfos;
begin
AAllItemViewInfos.Sort(@CompareAllItemViewInfos);
end;
procedure ProcessItemViewInfos(ACaptionLayout: TdxCaptionLayout);
var
AItemViewInfos: TList;
AGroupedCount: Integer;
procedure ExtractItemViewInfos;
var
I, ACount: Integer;
begin
I := AAllItemViewInfos.Count - 1;
while (I <> -1) and
(TdxLayoutItemViewInfo(AAllItemViewInfos[I]).CaptionLayout = ACaptionLayout) do
Dec(I);
ACount := AAllItemViewInfos.Count - 1 - I;
AItemViewInfos.Count := ACount;
Move(AAllItemViewInfos.List^[I + 1], AItemViewInfos.List^[0],
ACount * SizeOf(Pointer));
AAllItemViewInfos.Count := I + 1;
end;
procedure SortItemViewInfos;
begin
AItemViewInfos.Sort(@CompareItemViewInfos);
end;
function FindGroup: Boolean;
var
AItemViewInfo1, AItemViewInfo2: TdxLayoutItemViewInfo;
begin
AItemViewInfo1 := AItemViewInfos[0];
AGroupedCount := 1;
while AGroupedCount < AItemViewInfos.Count do
begin
AItemViewInfo2 := AItemViewInfos[AGroupedCount];
if CompareItemViewInfos(AItemViewInfo1, AItemViewInfo2) <> 0 then
Break;
Inc(AGroupedCount);
end;
Result := AGroupedCount <> 1;
end;
procedure AlignControls;
function IsCaptionLayoutHorizontal: Boolean;
begin
Result := ACaptionLayout in [clLeft, clRight];
end;
function GetMaxCaptionSize: Integer;
var
I, ACaptionSize: Integer;
begin
Result := 0;
for I := 0 to AGroupedCount - 1 do
begin
with TdxLayoutItemViewInfo(AItemViewInfos[I]).CaptionViewInfo do
if IsCaptionLayoutHorizontal then
ACaptionSize := Width
else
ACaptionSize := Height;
Result := Max(Result, ACaptionSize);
end;
end;
procedure AssignCaptionSizes(AMaxCaptionSize: Integer);
var
I: Integer;
begin
for I := 0 to AGroupedCount - 1 do
with TdxLayoutItemViewInfo(AItemViewInfos[I]).CaptionViewInfo do
if IsCaptionLayoutHorizontal then
Width := AMaxCaptionSize
else
Height := AMaxCaptionSize;
end;
begin
AssignCaptionSizes(GetMaxCaptionSize);
CalculateItemsViewInfo;
end;
procedure RemoveProcessedItemViewInfos;
begin
Move(AItemViewInfos.List^[AGroupedCount], AItemViewInfos.List^[0],
(AItemViewInfos.Count - AGroupedCount) * SizeOf(Pointer));
AItemViewInfos.Count := AItemViewInfos.Count - AGroupedCount;
end;
begin
AItemViewInfos := TList.Create;
try
ExtractItemViewInfos;
while AItemViewInfos.Count <> 0 do
begin
SortItemViewInfos;
if FindGroup then
AlignControls;
RemoveProcessedItemViewInfos;
end;
finally
AItemViewInfos.Free;
end;
end;
begin
AAllItemViewInfos := TList.Create;
try
FindAllItemViewInfos(ItemsViewInfo);
SortAllItemViewInfos;
for ACaptionLayout := Low(ACaptionLayout) to High(ACaptionLayout) do
ProcessItemViewInfos(ACaptionLayout);
finally
AAllItemViewInfos.Free;
end;
end;
procedure TdxLayoutControlViewInfo.CalculateItemsViewInfo;
begin
ResetContentBounds;
ItemsViewInfo.Calculate(ContentBounds);
end;
procedure TdxLayoutControlViewInfo.CalculateTabOrders;
var
AAvailTabOrder: Integer;
begin
AAvailTabOrder := 0;
ItemsViewInfo.CalculateTabOrders(AAvailTabOrder);
end;
function TdxLayoutControlViewInfo.GetIsTransparent: Boolean;
begin
Result := HasBackground;
end;
function TdxLayoutControlViewInfo.HasBackground: Boolean;
begin
Result := Control.HasBackground;
end;
function TdxLayoutControlViewInfo.NeedHighlightRoot: Boolean;
begin
Result := Control.HighlightRoot and Control.IsDesigning;
end;
procedure TdxLayoutControlViewInfo.PrepareData;
begin
RecreateViewInfos;
end;
procedure TdxLayoutControlViewInfo.ResetContentBounds;
begin
SetRectEmpty(FContentBounds);
end;
function TdxLayoutControlViewInfo.GetCanvas: TcxCanvas;
begin
if Control.HandleAllocated then
begin
FreeAndNil(FCanvas);
Result := Control.Canvas;
end
else
begin
if FCanvas = nil then
FCanvas := TcxScreenCanvas.Create;
Result := FCanvas;
end;
end;
function TdxLayoutControlViewInfo.GetClientBounds: TRect;
begin
Result := FControl.ClientBounds;
end;
function TdxLayoutControlViewInfo.GetContentBounds: TRect;
function CalculateContentWidth: Integer;
begin
//#DG if acsWidth in Control.AutoContentSizes then
if ItemsViewInfo.AlignHorz = ahClient then
Result := Max(cxRectWidth(ClientBounds), ItemsViewInfo.MinWidth)
else
Result := ItemsViewInfo.CalculateWidth;
end;
function CalculateContentHeight: Integer;
begin
//#DG if acsHeight in Control.AutoContentSizes then
if ItemsViewInfo.AlignVert = avClient then
Result := Max(cxRectHeight(ClientBounds), ItemsViewInfo.MinHeight)
else
Result := ItemsViewInfo.CalculateHeight;
end;
begin
if IsRectEmpty(FContentBounds) then
FContentBounds := cxRectBounds(-Control.LeftPos, -Control.TopPos, CalculateContentWidth, CalculateContentHeight);
Result := FContentBounds;
end;
procedure TdxLayoutControlViewInfo.Calculate;
begin
PrepareData;
CalculateItemsViewInfo;
AlignItems;
if Control.AutoControlAlignment then
begin
AutoAlignControls;
AlignItems;
end;
Control.CheckPositions;
DoCalculateTabOrders;
if Control.HandleAllocated then
Control.IsPlaceControlsNeeded := True;
end;
procedure TdxLayoutControlViewInfo.DoCalculateTabOrders;
begin
if Control.AutoControlTabOrders then
CalculateTabOrders;
end;
function TdxLayoutControlViewInfo.GetHitTest(const P: TPoint): TdxCustomLayoutHitTest;
begin
//{#MS
if Control.Customization and PtInRect(Control.CustomizeForm.BoundsRect, Control.ClientToScreen(P)) then
Result := TdxLayoutControlCustomizeForm(Control.CustomizeForm).GetHitTest(Control.CustomizeForm.ScreenToClient(Control.ClientToScreen(P)))
else
begin
if PtInRect(ClientBounds, P) and not (Control.ShowDesignSelectors and PtInRect(Control.GetDesignSelectorRect, P)) then
begin
Result := ItemsViewInfo.GetHitTest(P);
if Result = nil then
Result := TdxLayoutClientAreaHitTest.Instance;
end
else
Result := nil;
end;
if Result = nil then
Result := TdxLayoutNoneHitTest.Instance;
end;
function TdxLayoutControlViewInfo.GetHitTest(X, Y: Integer): TdxCustomLayoutHitTest;
begin
Result := GetHitTest(Point(X, Y));
end;
function TdxLayoutControlViewInfo.GetItemWithMouse(const P: TPoint): TdxCustomLayoutItem;
begin
Result := ItemsViewInfo.GetItemWithMouse(P);
end;
{ TdxCustomLayoutElementViewInfo }
procedure TdxCustomLayoutElementViewInfo.Calculate(const ABounds: TRect);
begin
FBounds := ABounds;
end;
{ TdxCustomLayoutItemElementViewInfo }
constructor TdxCustomLayoutItemElementViewInfo.Create(AItemViewInfo: TdxCustomLayoutItemViewInfo);
begin
inherited Create;
FItemViewInfo := AItemViewInfo;
end;
function TdxCustomLayoutItemElementViewInfo.CalculateMinHeight: Integer;
begin
Result := 0;
end;
function TdxCustomLayoutItemElementViewInfo.CalculateMinWidth: Integer;
begin
Result := 0;
end;
function TdxCustomLayoutItemElementViewInfo.CalculateHeight: Integer;
begin
Result := 0;
end;
function TdxCustomLayoutItemElementViewInfo.CalculateWidth: Integer;
begin
Result := 0;
end;
function TdxCustomLayoutItemElementViewInfo.GetHeight: Integer;
begin
Result := FHeight;
if Result = 0 then
begin
Result := cxRectHeight(Bounds);
if Result = 0 then
Result := CalculateHeight;
end;
end;
function TdxCustomLayoutItemElementViewInfo.GetItem: TdxCustomLayoutItem;
begin
Result := FItemViewInfo.Item;
end;
function TdxCustomLayoutItemElementViewInfo.GetLayoutLookAndFeel: TdxCustomLayoutLookAndFeel;
begin
Result := FItemViewInfo.LayoutLookAndFeel;
end;
function TdxCustomLayoutItemElementViewInfo.GetWidth: Integer;
begin
Result := FWidth;
if Result = 0 then
begin
Result := cxRectWidth(Bounds);
if Result = 0 then
Result := CalculateWidth;
end;
end;
procedure TdxCustomLayoutItemElementViewInfo.SetHeight(Value: Integer);
begin
FHeight := Value;
end;
procedure TdxCustomLayoutItemElementViewInfo.SetWidth(Value: Integer);
begin
FWidth := Value;
end;
function TdxCustomLayoutItemElementViewInfo.GetEnabled: Boolean;
begin
Result := FItemViewInfo.Enabled;
end;
function TdxCustomLayoutItemElementViewInfo.GetEnabledForWork: Boolean;
begin
Result := FItemViewInfo.EnabledForWork;
end;
function TdxCustomLayoutItemElementViewInfo.GetCursor(X, Y: Integer): TCursor;
begin
Result := crDefault;
end;
function TdxCustomLayoutItemElementViewInfo.GetVisible: Boolean;
begin
Result := False;
end;
procedure TdxCustomLayoutItemElementViewInfo.Invalidate(const ABounds: TRect);
begin
Item.Container.InvalidateRect(ABounds, False);
end;
procedure TdxCustomLayoutItemElementViewInfo.MouseEnter;
begin
end;
procedure TdxCustomLayoutItemElementViewInfo.MouseLeave;
begin
Pressed := False;
end;
procedure TdxCustomLayoutItemElementViewInfo.MouseDown(Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
Pressed := True;
end;
procedure TdxCustomLayoutItemElementViewInfo.MouseMove(Shift: TShiftState;
X, Y: Integer);
begin
end;
procedure TdxCustomLayoutItemElementViewInfo.MouseUp(Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
Pressed := False;
end;
function TdxCustomLayoutItemElementViewInfo.WantsMouse(X, Y: Integer): Boolean;
begin
Result := Visible and PtInRect(Bounds, Point(X, Y));
end;
{ TdxCustomLayoutItemCaptionViewInfo }
function TdxCustomLayoutItemCaptionViewInfo.GetCanvas: TcxCanvas;
begin
Result := ItemViewInfo.ContainerViewInfo.Canvas;
end;
function TdxCustomLayoutItemCaptionViewInfo.GetIsCustomization: Boolean;
begin
Result := FItemViewInfo.IsCustomization;
end;
function TdxCustomLayoutItemCaptionViewInfo.GetTextHeight: Integer;
var
R: TRect;
begin
if Item.CachedTextHeight = 0 then
begin
PrepareCanvas;
if MultiLine then
begin
R := Rect(0, 0, CalculateWidth - 1 {for disabling}, 0);
Canvas.TextExtent(Text, R, CalculateTextFlags);
Result := R.Bottom - R.Top;
end
else
Result := Canvas.TextHeight(Text);
Item.CachedTextHeight := Result;
end
else
Result := Item.CachedTextHeight;
if Text <> '' then
Inc(Result); // for disabling
end;
function TdxCustomLayoutItemCaptionViewInfo.GetTextWidth: Integer;
var
AText: string;
begin
AText := VisibleText;
PrepareCanvas;
Result := Canvas.TextWidth(AText);
if AText <> '' then
Inc(Result); // for disabling
end;
procedure TdxCustomLayoutItemCaptionViewInfo.SetHotTracked(Value: Boolean);
begin
if FHotTracked <> Value then
begin
FHotTracked := Value;
Invalidate(HotTrackBounds);
end;
end;
function TdxCustomLayoutItemCaptionViewInfo.GetCursor(X, Y: Integer): TCursor;
begin
if HotTracked and (htsHandPoint in HotTrackStyles) then
Result := crcxHandPoint
else
Result := inherited GetCursor(X, Y);
end;
function TdxCustomLayoutItemCaptionViewInfo.GetVisible: Boolean;
begin
Result := ItemViewInfo.HasCaption or (ItemViewInfo.IsDragImagePainted and ItemViewInfo.IsAvailable);
end;
procedure TdxCustomLayoutItemCaptionViewInfo.MouseDown(Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
inherited;
if CanDoCaptionClick(X, Y) then
Item.DoCaptionDown;
end;
procedure TdxCustomLayoutItemCaptionViewInfo.MouseLeave;
begin
inherited;
HotTracked := False;
end;
procedure TdxCustomLayoutItemCaptionViewInfo.MouseMove(Shift: TShiftState;
X, Y: Integer);
begin
inherited;
if IsHotTrackable then
HotTracked := IsPointInHotTrackBounds(Point(X, Y));
end;
procedure TdxCustomLayoutItemCaptionViewInfo.MouseUp(Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
APressed: Boolean;
begin
APressed := Pressed;
inherited;
if CanDoCaptionClick(X, Y) and APressed then
Item.DoCaptionClick;
end;
function TdxCustomLayoutItemCaptionViewInfo.GetColor: TColor;
begin
Result := ItemViewInfo.Color;
end;
function TdxCustomLayoutItemCaptionViewInfo.GetFont: TFont;
begin
Result := Options.GetFont(Item.Container);
end;
function TdxCustomLayoutItemCaptionViewInfo.GetHotTrackBounds: TRect;
begin
Result := TextAreaBounds;
end;
function TdxCustomLayoutItemCaptionViewInfo.GetHotTrackStyles: TdxLayoutHotTrackStyles;
begin
Result := Options.HotTrackStyles;
end;
function TdxCustomLayoutItemCaptionViewInfo.GetIsDefaultColor: Boolean;
begin
Result := ItemViewInfo.IsDefaultColor;
end;
function TdxCustomLayoutItemCaptionViewInfo.GetIsHotTrackable: Boolean;
begin
Result := not IsCustomization and EnabledForWork and Options.HotTrack;
end;
function TdxCustomLayoutItemCaptionViewInfo.CalculateTextFlags: Integer;
const
MultiLines: array[Boolean] of Integer = (cxSingleLine, cxWordBreak);
AlignsVert: array[TdxAlignmentVert] of Integer =
(cxAlignTop, cxAlignVCenter, cxAlignBottom);
begin
Result := MultiLines[MultiLine] or cxAlignmentsHorz[AlignHorz] or AlignsVert[AlignVert];
if Item.CaptionOptions.ShowAccelChar then
Inc(Result, cxShowPrefix);
end;
function TdxCustomLayoutItemCaptionViewInfo.CanDoCaptionClick(X, Y: Integer): Boolean;
begin
Result := EnabledForWork and IsPointInHotTrackBounds(Point(X, Y));
end;
function TdxCustomLayoutItemCaptionViewInfo.GetAlignHorz: TAlignment;
begin
Result := Item.CaptionOptions.AlignHorz;
end;
function TdxCustomLayoutItemCaptionViewInfo.GetIsTextUnderlined: Boolean;
begin
Result :=
IsHotTrackable and not HotTracked and (htsUnderlineCold in HotTrackStyles) or
HotTracked and (htsUnderlineHot in HotTrackStyles);
end;
function TdxCustomLayoutItemCaptionViewInfo.GetIsTransparent: Boolean;
begin
Result := ItemViewInfo.ContainerViewInfo.HasBackground and IsDefaultColor;
end;
function TdxCustomLayoutItemCaptionViewInfo.GetOptions: TdxLayoutLookAndFeelCaptionOptions;
begin
Result := ItemViewInfo.Options.CaptionOptions;
end;
function TdxCustomLayoutItemCaptionViewInfo.GetText: string;
begin
Result := Item.Caption;
end;
function TdxCustomLayoutItemCaptionViewInfo.GetTextAreaBounds: TRect;
begin
Result := Bounds;
if Enabled and (Text <> '') then
with Result do
begin
Dec(Right);
Dec(Bottom);
end;
end;
function TdxCustomLayoutItemCaptionViewInfo.GetTextColor: TColor;
begin
if HotTracked then
Result := GetTextHotColor
else
Result := GetTextNormalColor;
end;
function TdxCustomLayoutItemCaptionViewInfo.GetTextHotColor: TColor;
begin
Result := Options.GetTextHotColor;
end;
function TdxCustomLayoutItemCaptionViewInfo.GetTextNormalColor: TColor;
begin
Result := Options.GetTextColor;
end;
function TdxCustomLayoutItemCaptionViewInfo.GetVisibleText: string;
begin
Result := Text;
if Item.CaptionOptions.ShowAccelChar then
Result := StripHotKey(Result);
end;
function TdxCustomLayoutItemCaptionViewInfo.IsPointInHotTrackBounds(const P: TPoint): Boolean;
var
ABounds: TRectArray;
I: Integer;
begin
Result := False;
PrepareCanvas;
Canvas.GetTextStringsBounds(Text, TextAreaBounds,
CalculateTextFlags, Enabled, ABounds);
try
for I := 0 to High(ABounds) do
begin
Result := PtInRect(ABounds[I], P);
if Result then Break;
end;
finally
ABounds := nil;
end;
end;
procedure TdxCustomLayoutItemCaptionViewInfo.PrepareCanvas;
begin
Canvas.Font := Font;
end;
function TdxCustomLayoutItemCaptionViewInfo.CalculateHeight: Integer;
begin
if Visible then
Result := TextHeight
else
Result := 0;
end;
function TdxCustomLayoutItemCaptionViewInfo.CalculateWidth: Integer;
begin
if Visible then
Result := TextWidth
else
Result := 0;
end;
{ TdxCustomLayoutItemViewInfo }
constructor TdxCustomLayoutItemViewInfo.Create(AContainerViewInfo: TdxLayoutControlViewInfo;
AParentViewInfo: TdxLayoutGroupViewInfo; AItem: TdxCustomLayoutItem);
begin
inherited Create;
FContainerViewInfo := AContainerViewInfo;
FParentViewInfo := AParentViewInfo;
FNotifyComponent := TcxFreeNotificator.Create(nil);
FNotifyComponent.OnFreeNotification := FreeNotification;
FItem := AItem;
FItem.FViewInfo := Self;
FItem.FreeNotification(FNotifyComponent);
CreateViewInfos;
end;
destructor TdxCustomLayoutItemViewInfo.Destroy;
begin
DestroyViewInfos;
if FItem <> nil then
FItem.FViewInfo := nil;
FreeAndNil(FNotifyComponent);
inherited;
end;
function TdxCustomLayoutItemViewInfo.GetAlignHorz: TdxLayoutAlignHorz;
begin
//#DG Result := Item.AlignHorz;
Result := Item.GetRealAlignHorz;
end;
function TdxCustomLayoutItemViewInfo.GetAlignVert: TdxLayoutAlignVert;
begin
//#DG Result := Item.AlignVert;
Result := Item.GetRealAlignVert;
end;
function TdxCustomLayoutItemViewInfo.GetBackgroundBounds: TRect;
begin
if IsDragImagePainted then
Result := SelectionBorderRect
else
Result := Bounds;
end;
function TdxCustomLayoutItemViewInfo.GetCanPaint: Boolean;
begin
Result := ActuallyVisible or
IsDragImagePainted and (IsDragged or IsDraggedWithParent and ParentViewInfo.CanPaint and
ParentViewInfo.Specific.AllowDrawChild(Item));
end;
function TdxCustomLayoutItemViewInfo.GetIsAvailable: Boolean;
begin
Result := Item.IsAvailable;
end;
function TdxCustomLayoutItemViewInfo.GetIsCustomization: Boolean;
begin
Result := FItem.Container.IsCustomization;
end;
function TdxCustomLayoutItemViewInfo.GetIsDragged: Boolean;
begin
Result := Item.IsDragged;
end;
function TdxCustomLayoutItemViewInfo.GetIsDraggedWithParent: Boolean;
begin
Result := (ParentViewInfo <> nil) and (ParentViewInfo.IsDragged or ParentViewInfo.IsDraggedWithParent);
end;
function TdxCustomLayoutItemViewInfo.GetIsDragImagePainted: Boolean;
begin
Result := ContainerViewInfo.IsDragImagePainted;
end;
function TdxCustomLayoutItemViewInfo.GetLayoutLookAndFeel: TdxCustomLayoutLookAndFeel;
begin
Result := Item.GetLayoutLookAndFeel;
end;
procedure TdxCustomLayoutItemViewInfo.PaintSelectionLayer;
var
ABitmap, ABackgroundBitmap: TcxAlphaBitmap;
begin
if Selected and ActuallyVisible then
begin
ABitmap := ContainerViewInfo.SelectionLayer.SelectionImage;
ABackgroundBitmap := TcxAlphaBitmap.CreateSize(SelectionBorderRect);
try
ABackgroundBitmap.cxCanvas.FillRect(ABackgroundBitmap.ClientRect, dxLayoutControlSelectionDefaultColor);
ABackgroundBitmap.SetAlphaChannel(dxLayoutSelectionDefaultAlphaChannel);
ABitmap.CopyBitmap(ABackgroundBitmap, SelectionBorderRect, cxNullPoint);
finally
ABackgroundBitmap.Free;
end;
dxDrawSelectionMarkers(ABitmap.cxCanvas, SelectionBorderRect, dxLayoutSelectionBorderDefaultColor,
dxLayoutSelectionBorderMarkerInnerDefaultColor, dxSelectionMarkerWidth);
ABitmap.cxCanvas.FrameRect(SelectionBorderRect, dxLayoutSelectionBorderDefaultColor, 1, cxBordersAll, True);
end;
end;
function TdxCustomLayoutItemViewInfo.IsParentLocked: Boolean;
begin
Result := (ParentViewInfo <> nil) and ParentViewInfo.IsLocked;
end;
function TdxCustomLayoutItemViewInfo.IsParentSelected: Boolean;
begin
Result := (ParentViewInfo <> nil) and (ParentViewInfo.Selected or ParentViewInfo.IsParentSelected);
end;
function TdxCustomLayoutItemViewInfo.GetMinHeight: Integer;
begin
if AlignVert = avClient then
Result := CalculateMinHeight
else
Result := CalculateHeight;
end;
function TdxCustomLayoutItemViewInfo.GetMinWidth: Integer;
begin
if AlignHorz = ahClient then
Result := CalculateMinWidth
else
Result := CalculateWidth;
end;
function TdxCustomLayoutItemViewInfo.GetHeight: Integer;
begin
Result := CalculateHeight;
end;
function TdxCustomLayoutItemViewInfo.GetWidth: Integer;
begin
Result := CalculateWidth;
end;
function TdxCustomLayoutItemViewInfo.GetOffset(ASide: TdxLayoutSide): Integer;
begin
Result := FOffsets[ASide];
if Result = 0 then
Result := CalculateOffset(ASide);
end;
function TdxCustomLayoutItemViewInfo.GetOffsetsHeight: Integer;
begin
Result := Offsets[sdTop] + Offsets[sdBottom];
end;
function TdxCustomLayoutItemViewInfo.GetOffsetsWidth: Integer;
begin
Result := Offsets[sdLeft] + Offsets[sdRight];
end;
function TdxCustomLayoutItemViewInfo.GetSelected: Boolean;
begin
Result := Item.Container.IsComponentSelected(Item);
end;
function TdxCustomLayoutItemViewInfo.GetSelectionBorderRect: TRect;
function CanUseSelectionOffset: Boolean;
begin
Result := (ParentViewInfo = nil) or
(ParentViewInfo.UseItemOffset and (ParentViewInfo.ItemOffset > Integer(dxLayoutSelectionOffset) div 2));
end;
function GetSelectionBoundsOffset: Integer;
begin
if CanUseSelectionOffset then
Result := dxLayoutSelectionOffset
else
Result := 0;
if Item.IsRoot then
Result := -Result;
end;
var
ABoundsOffset: Integer;
begin
Result := Bounds;
ABoundsOffset := GetSelectionBoundsOffset;
InflateRect(Result, ABoundsOffset, ABoundsOffset);
end;
function TdxCustomLayoutItemViewInfo.GetSelectionArea: TRect;
begin
Result := SelectionBorderRect;
InflateRect(Result, dxSelectionMarkerWidth div 2, dxSelectionMarkerWidth div 2);
end;
procedure TdxCustomLayoutItemViewInfo.SetElementWithMouse(Value: TdxCustomLayoutItemElementViewInfo);
begin
if FElementWithMouse <> Value then
begin
if FElementWithMouse <> nil then
FElementWithMouse.MouseLeave;
FElementWithMouse := Value;
if FElementWithMouse <> nil then
FElementWithMouse.MouseEnter;
end;
end;
procedure TdxCustomLayoutItemViewInfo.SetOffset(ASide: TdxLayoutSide; Value: Integer);
begin
FOffsets[ASide] := Value;
end;
function TdxCustomLayoutItemViewInfo.CreateHitTest: TdxCustomLayoutItemHitTest;
begin
Result := GetHitTestClass.Instance as TdxCustomLayoutItemHitTest;
Result.Item := Item;
end;
procedure TdxCustomLayoutItemViewInfo.FreeNotification(AComponent: TComponent);
begin
FItem := nil;
end;
procedure TdxCustomLayoutItemViewInfo.DoCreateViewInfos;
begin
FCaptionViewInfo := GetCaptionViewInfoClass.Create(Self);
FElements.Add(FCaptionViewInfo);
end;
procedure TdxCustomLayoutItemViewInfo.CreateViewInfos;
begin
FElements := TObjectList.Create;
DoCreateViewInfos;
end;
procedure TdxCustomLayoutItemViewInfo.DestroyViewInfos;
begin
FreeAndNil(FElements);
end;
function TdxCustomLayoutItemViewInfo.CanDrawBackground: Boolean;
begin
Result := HasBackground;
end;
function TdxCustomLayoutItemViewInfo.GetBackgroundColor: TColor;
begin
if IsDragImagePainted then
Result := dxLayoutSelectionDefaultColor
else
Result := Color;
end;
function TdxCustomLayoutItemViewInfo.CalculateMinHeight: Integer;
begin
Result := DoCalculateHeight(True);
end;
function TdxCustomLayoutItemViewInfo.CalculateMinWidth: Integer;
begin
Result := DoCalculateWidth(True);
end;
function TdxCustomLayoutItemViewInfo.CalculateOffset(ASide: TdxLayoutSide): Integer;
begin
case ASide of
sdLeft:
Result := Item.Offsets.Left;
sdRight:
Result := Item.Offsets.Right;
sdTop:
Result := Item.Offsets.Top;
sdBottom:
Result := Item.Offsets.Bottom;
else
Result := 0;
end;
end;
function TdxCustomLayoutItemViewInfo.GetAreaPart(const P: TPoint): TdxLayoutAreaPart;
const
Parts: array[Boolean, Boolean] of TdxLayoutAreaPart = ((apBottom, apRight), (apLeft, apTop));
function GetSign(const P1, P2, P: TPoint): Integer;
begin
Result := (P.X - P1.X) * (P2.Y - P1.Y) - (P.Y - P1.Y) * (P2.X - P1.X);
end;
var
ASign1, ASign2: Integer;
begin
with Bounds do
begin
ASign1 := GetSign(Point(Left, Bottom), Point(Right, Top), P);
ASign2 := GetSign(TopLeft, BottomRight, P);
end;
Result := Parts[ASign1 >= 0, ASign2 >= 0];
end;
function TdxCustomLayoutItemViewInfo.GetActuallyVisible: Boolean;
begin
Result := Item.ActuallyVisible;
end;
function TdxCustomLayoutItemViewInfo.DoCalculateHeight(AIsMinHeight: Boolean): Integer;
begin
Result := OffsetsHeight;
end;
function TdxCustomLayoutItemViewInfo.DoCalculateWidth(AIsMinWidth: Boolean): Integer;
begin
Result := OffsetsWidth;
end;
function TdxCustomLayoutItemViewInfo.GetCursor(X, Y: Integer): TCursor;
var
I: Integer;
begin
for I := 0 to ElementCount - 1 do
if Elements[I].WantsMouse(X, Y) then
begin
Result := Elements[I].GetCursor(X, Y);
Exit;
end;
Result := crDefault;
end;
function TdxCustomLayoutItemViewInfo.GetElement(AIndex: Integer): TdxCustomLayoutItemElementViewInfo;
begin
if (AIndex >= 0) and (AIndex < GetElementCount) then
Result := TdxCustomLayoutItemElementViewInfo(FElements[AIndex])
else
Result := nil;
end;
function TdxCustomLayoutItemViewInfo.GetElementCount: Integer;
begin
Result := FElements.Count;
end;
function TdxCustomLayoutItemViewInfo.GetEnabled: Boolean;
begin
Result := Item.Enabled;
end;
function TdxCustomLayoutItemViewInfo.GetEnabledForWork: Boolean;
begin
Result := Item.EnabledForWork;
end;
function TdxCustomLayoutItemViewInfo.GetIsTransparent: Boolean;
begin
Result := ContainerViewInfo.HasBackground and IsDefaultColor;
end;
function TdxCustomLayoutItemViewInfo.HasBackground: Boolean;
begin
Result := (ParentViewInfo = nil) {IsRoot} or
(LayoutLookAndFeel <> ParentViewInfo.LayoutLookAndFeel) or
IsDragImagePainted and IsDragged;
end;
function TdxCustomLayoutItemViewInfo.HasCaption: Boolean;
begin
Result := Item.HasCaption;
end;
function TdxCustomLayoutItemViewInfo.HasBorder: Boolean;
begin
Result := False;
end;
procedure TdxCustomLayoutItemViewInfo.MouseEnter;
begin
end;
procedure TdxCustomLayoutItemViewInfo.MouseLeave;
begin
ElementWithMouse := nil;
end;
procedure TdxCustomLayoutItemViewInfo.MouseDown(Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if ElementWithMouse <> nil then
ElementWithMouse.MouseDown(Button, Shift, X, Y);
end;
procedure TdxCustomLayoutItemViewInfo.MouseMove(Shift: TShiftState; X, Y: Integer);
var
I: Integer;
begin
for I := 0 to ElementCount - 1 do
if Elements[I].WantsMouse(X, Y) then
begin
ElementWithMouse := Elements[I];
Elements[I].MouseMove(Shift, X, Y);
Exit;
end;
ElementWithMouse := nil;
end;
procedure TdxCustomLayoutItemViewInfo.MouseUp(Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if ElementWithMouse <> nil then
ElementWithMouse.MouseUp(Button, Shift, X, Y);
end;
procedure TdxCustomLayoutItemViewInfo.Calculate(const ABounds: TRect);
begin
inherited;
Inc(FBounds.Left, Offsets[sdLeft]);
Inc(FBounds.Top, Offsets[sdTop]);
Dec(FBounds.Right, Offsets[sdRight]);
Dec(FBounds.Bottom, Offsets[sdBottom]);
end;
function TdxCustomLayoutItemViewInfo.CalculateHeight: Integer;
begin
Result := DoCalculateHeight(False);
end;
function TdxCustomLayoutItemViewInfo.CalculateWidth: Integer;
begin
Result := DoCalculateWidth(False);
end;
function TdxCustomLayoutItemViewInfo.GetHitTest(const P: TPoint): TdxCustomLayoutHitTest;
begin
if not IsParentLocked and PtInRect(Bounds, P) and ActuallyVisible then
Result := CreateHitTest
else
Result := nil;
end;
function TdxCustomLayoutItemViewInfo.GetItemWithMouse(const P: TPoint): TdxCustomLayoutItem;
begin
if not IsParentLocked and PtInRect(Bounds, P) and ActuallyVisible then
Result := Item
else
Result := nil;
end;
procedure TdxCustomLayoutItemViewInfo.ResetOffset(ASide: TdxLayoutSide);
begin
FOffsets[ASide] := 0;
end;
{ TdxLayoutItemCaptionViewInfo }
function TdxLayoutItemCaptionViewInfo.GetItem: TdxLayoutItem;
begin
Result := TdxLayoutItem(inherited GetItem);
end;
function TdxLayoutItemCaptionViewInfo.GetItemViewInfo: TdxLayoutItemViewInfo;
begin
Result := TdxLayoutItemViewInfo(inherited ItemViewInfo);
end;
function TdxLayoutItemCaptionViewInfo.GetAlignVert: TdxAlignmentVert;
begin
Result := Item.CaptionOptions.AlignVert;
end;
function TdxLayoutItemCaptionViewInfo.GetIsFixedWidth: Boolean;
begin
Result := Item.CaptionOptions.Width <> 0;
end;
function TdxLayoutItemCaptionViewInfo.GetMultiLine: Boolean;
begin
Result := IsFixedWidth;
end;
function TdxLayoutItemCaptionViewInfo.GetTextAreaBounds: TRect;
var
ADelta: Integer;
begin
Result := inherited GetTextAreaBounds;
if IsFixedWidth then
with Result do
begin
ADelta := Width - CalculateWidth;
case AlignHorz of
taLeftJustify:
Dec(Right, ADelta);
taRightJustify:
Inc(Left, ADelta);
taCenter:
begin
Inc(Left, ADelta div 2);
Dec(Right, ADelta - ADelta div 2);
end;
end;
end;
end;
function TdxLayoutItemCaptionViewInfo.CalculateWidth: Integer;
begin
if Visible and IsFixedWidth then
Result := Item.CaptionOptions.Width
else
Result := inherited CalculateWidth;
end;
function TdxLayoutItemCaptionViewInfo.CalculateMinWidth: Integer;
begin
if FWidth = 0 then
Result := CalculateWidth
else
Result := Width;
end;
{ TdxLayoutItemControlViewInfo }
function TdxLayoutItemControlViewInfo.GetBorderColor: TColor;
begin
Result := ItemViewInfo.Options.GetControlBorderColor;
end;
function TdxLayoutItemControlViewInfo.GetBorderStyle: TdxLayoutBorderStyle;
begin
Result := ItemViewInfo.Options.ControlBorderStyle;
end;
function TdxLayoutItemControlViewInfo.GetControl: TControl;
begin
Result := Item.Control;
end;
function TdxLayoutItemControlViewInfo.GetItem: TdxLayoutItem;
begin
Result := TdxLayoutItem(inherited Item);
end;
function TdxLayoutItemControlViewInfo.GetItemViewInfo: TdxLayoutItemViewInfo;
begin
Result := TdxLayoutItemViewInfo(inherited ItemViewInfo);
end;
function TdxLayoutItemControlViewInfo.GetOpaqueControl: Boolean;
begin
Result := Item.ControlOptions.Opaque;
end;
function TdxLayoutItemControlViewInfo.GetVisible: Boolean;
begin
Result := ItemViewInfo.HasControl and not ItemViewInfo.IsAvailable;
end;
function TdxLayoutItemControlViewInfo.CalculateControlBounds: TRect;
begin
Result := Bounds;
Inc(Result.Left, BorderWidths[sdLeft]);
Dec(Result.Right, BorderWidths[sdRight]);
Inc(Result.Top, BorderWidths[sdTop]);
Dec(Result.Bottom, BorderWidths[sdBottom]);
end;
function TdxLayoutItemControlViewInfo.GetBorderWidth(ASide: TdxLayoutSide): Integer;
begin
if HasBorder then
Result := LayoutLookAndFeel.ItemControlBorderWidths[ASide]
else
Result := 0
end;
function TdxLayoutItemControlViewInfo.GetControlAreaHeight(AControlHeight: Integer): Integer;
begin
Result := BorderWidths[sdTop] + AControlHeight + BorderWidths[sdBottom];
end;
function TdxLayoutItemControlViewInfo.GetControlAreaWidth(AControlWidth: Integer): Integer;
begin
Result := BorderWidths[sdLeft] + AControlWidth + BorderWidths[sdRight];
end;
function TdxLayoutItemControlViewInfo.HasBorder: Boolean;
begin
Result := Item.ControlOptions.ShowBorder and not ItemViewInfo.IsAvailable;
end;
procedure TdxLayoutItemControlViewInfo.Calculate(const ABounds: TRect);
begin
inherited;
FControlBounds := CalculateControlBounds;
end;
procedure TdxLayoutItemControlViewInfo.CalculateTabOrder(var AAvailTabOrder: Integer);
begin
if Item.HasWinControl then
begin
TWinControl(Control).TabOrder := AAvailTabOrder;
Inc(AAvailTabOrder);
end;
end;
function TdxLayoutItemControlViewInfo.CalculateMinHeight: Integer;
begin
if Item.ControlOptions.FixedSize then
Result := CalculateHeight
else
if Visible then
Result := GetControlAreaHeight(Item.ControlOptions.MinHeight)
else
Result := 0;
end;
function TdxLayoutItemControlViewInfo.CalculateMinWidth: Integer;
begin
if Item.ControlOptions.FixedSize then
Result := CalculateWidth
else
if Visible then
Result := GetControlAreaWidth(Item.ControlOptions.MinWidth)
else
Result := 0;
end;
function TdxLayoutItemControlViewInfo.CalculateHeight: Integer;
begin
if Visible then
Result := GetControlAreaHeight(Item.OriginalControlSize.Y)
else
Result := 0;
end;
function TdxLayoutItemControlViewInfo.CalculateWidth: Integer;
begin
if Visible then
Result := GetControlAreaWidth(Item.OriginalControlSize.X)
else
Result := 0;
end;
{ TdxLayoutItemViewInfo }
function TdxLayoutItemViewInfo.GetCaptionViewInfo: TdxLayoutItemCaptionViewInfo;
begin
Result := TdxLayoutItemCaptionViewInfo(inherited CaptionViewInfo);
end;
function TdxLayoutItemViewInfo.GetItem: TdxLayoutItem;
begin
Result := TdxLayoutItem(inherited Item);
end;
function TdxLayoutItemViewInfo.GetOptionsEx: TdxLayoutLookAndFeelItemOptions;
begin
Result := TdxLayoutLookAndFeelItemOptions(inherited Options);
end;
function TdxLayoutItemViewInfo.GetDesignSelectorRect: TRect;
const
Offset = 3;
Width = 10;
var
AControlBounds: TRect;
begin
AControlBounds := ControlViewInfo.ControlBounds;
Result := AControlBounds;
Result.Left := Result.Right - Width;
if cxRectWidth(AControlBounds) >= 2 * Offset + Width then
OffsetRect(Result, -Offset, 0);
Result.Top := Result.Bottom - Width;
if cxRectHeight(AControlBounds) >= 2 * Offset + Width then
OffsetRect(Result, 0, -Offset);
end;
procedure TdxLayoutItemViewInfo.DoCreateViewInfos;
begin
inherited;
FControlViewInfo := GetControlViewInfoClass.Create(Self);
FElements.Add(FControlViewInfo);
end;
function TdxLayoutItemViewInfo.GetCaptionViewInfoClass: TdxCustomLayoutItemCaptionViewInfoClass;
begin
Result := TdxLayoutItemCaptionViewInfo;
end;
function TdxLayoutItemViewInfo.GetControlViewInfoClass: TdxLayoutItemControlViewInfoClass;
begin
Result := TdxLayoutItemControlViewInfo;
end;
function TdxLayoutItemViewInfo.GetHitTestClass: TdxCustomLayoutItemHitTestClass;
begin
Result := TdxLayoutItemHitTest;
end;
function TdxLayoutItemViewInfo.GetPainterClass: TdxCustomLayoutItemPainterClass;
begin
Result := TdxCustomLayoutItemPainterClass(LayoutLookAndFeel.GetItemPainterClass);
end;
procedure TdxLayoutItemViewInfo.CalculateViewInfosBounds(var ACaptionBounds,
AControlBounds: TRect);
var
ACaptionSize, AControlSize: TPoint;
ACaptionVisible, AControlVisible: Boolean;
procedure CalculateElementViewInfoSize(AElementViewInfo: TdxCustomLayoutItemElementViewInfo;
var ASize: TPoint; var AVisible: Boolean);
begin
AVisible := AElementViewInfo.Visible;
if AVisible then
ASize := Point(AElementViewInfo.Width, AElementViewInfo.Height)
else
ASize := cxNullPoint;
AVisible := AVisible and not cxPointIsEqual(ASize, cxNullPoint);
//AVisible := AVisible and (ASize.X <> 0) and (ASize.Y <> 0);
end;
procedure CalculateMainBounds;
procedure InitBounds(var ABounds: TRect; const ASize: TPoint; AVisible: Boolean);
begin
if AVisible then
ABounds := ContentBounds
else
SetRectEmpty(ABounds);
end;
procedure CalculateWithFixedControl;
begin
case CaptionLayout of
clLeft:
begin
AControlBounds.Left := AControlBounds.Right - AControlSize.X;
ACaptionBounds.Right := AControlBounds.Left - ControlOffsetHorz;
end;
clTop:
begin
AControlBounds.Top := AControlBounds.Bottom - AControlSize.Y;
ACaptionBounds.Bottom := AControlBounds.Top - ControlOffsetVert;
end;
clRight:
begin
AControlBounds.Right := AControlBounds.Left + AControlSize.X;
ACaptionBounds.Left := AControlBounds.Right + ControlOffsetHorz;
end;
clBottom:
begin
AControlBounds.Bottom := AControlBounds.Top + AControlSize.Y;
ACaptionBounds.Top := AControlBounds.Bottom + ControlOffsetVert;
end;
end
end;
procedure CalculateWithFixedCaption;
begin
case CaptionLayout of
clLeft:
begin
ACaptionBounds.Right := ACaptionBounds.Left + ACaptionSize.X;
AControlBounds.Left := ACaptionBounds.Right + ControlOffsetHorz;
end;
clTop:
begin
ACaptionBounds.Bottom := ACaptionBounds.Top + ACaptionSize.Y;
AControlBounds.Top := ACaptionBounds.Bottom + ControlOffsetVert;
end;
clRight:
begin
ACaptionBounds.Left := ACaptionBounds.Right - ACaptionSize.X;
AControlBounds.Right := ACaptionBounds.Left - ControlOffsetHorz;
end;
clBottom:
begin
ACaptionBounds.Top := ACaptionBounds.Bottom - ACaptionSize.Y;
AControlBounds.Bottom := ACaptionBounds.Top - ControlOffsetVert;
end;
end;
end;
begin
InitBounds(ACaptionBounds, ACaptionSize, ACaptionVisible);
InitBounds(AControlBounds, AControlSize, AControlVisible);
if ACaptionVisible and AControlVisible then
if Item.ControlOptions.FixedSize then
CalculateWithFixedControl
else
CalculateWithFixedCaption
else
if AControlVisible and Item.ControlOptions.FixedSize then
begin
AControlBounds.Right := AControlBounds.Left + AControlSize.X;
AControlBounds.Bottom := AControlBounds.Top + AControlSize.Y;
end;
end;
procedure CalculateRestBounds(var ABounds: TRect; const ASize: TPoint;
AAlignHorz: TAlignment; AAlignVert: TdxAlignmentVert);
begin
with ABounds do
case CaptionLayout of
clLeft, clRight:
case AAlignVert of
tavTop:
Bottom := Top + ASize.Y;
tavCenter:
begin
Top := (Top + Bottom - ASize.Y) div 2;
Bottom := Top + ASize.Y;
end;
tavBottom:
Top := Bottom - ASize.Y;
end;
clTop, clBottom:
case AAlignHorz of
taLeftJustify:
Right := Left + ASize.X;
taCenter:
begin
Left := (Left + Right - ASize.X) div 2;
Right := Left + ASize.X;
end;
taRightJustify:
Left := Right - ASize.X;
end;
end;
end;
begin
CalculateElementViewInfoSize(CaptionViewInfo, ACaptionSize, ACaptionVisible);
CalculateElementViewInfoSize(ControlViewInfo, AControlSize, AControlVisible);
CalculateMainBounds;
if ACaptionVisible then
begin
CalculateRestBounds(ACaptionBounds, ACaptionSize,
Item.CaptionOptions.AlignHorz, Item.CaptionOptions.AlignVert);
if AControlVisible and
((AlignHorz <> ahClient) or (CaptionLayout in [clLeft, clRight])) and
((AlignVert <> avClient) or (CaptionLayout in [clTop, clBottom])) then
CalculateRestBounds(AControlBounds, AControlSize, taLeftJustify, tavTop);
end;
end;
function TdxLayoutItemViewInfo.DoCalculateHeight(AIsMinHeight: Boolean): Integer;
var
AHeight: Integer;
begin
Result := CaptionViewInfo.Height;
if AIsMinHeight then
AHeight := ControlViewInfo.CalculateMinHeight
else
AHeight := ControlViewInfo.CalculateHeight;
case CaptionLayout of
clLeft, clRight:
Result := Max(Result, AHeight);
clTop, clBottom:
begin
if (Result <> 0) and ControlViewInfo.Visible{(AHeight <> 0)} then
Inc(Result, ControlOffsetVert);
Inc(Result, AHeight);
end;
else
Result := 0;
end;
Inc(Result, inherited DoCalculateHeight(AIsMinHeight));
end;
function TdxLayoutItemViewInfo.DoCalculateWidth(AIsMinWidth: Boolean): Integer;
var
AWidth: Integer;
begin
if AIsMinWidth then
begin
Result := CaptionViewInfo.CalculateMinWidth;
AWidth := ControlViewInfo.CalculateMinWidth;
end
else
begin
Result := CaptionViewInfo.Width;
AWidth := ControlViewInfo.CalculateWidth;
end;
case CaptionLayout of
clLeft, clRight:
begin
if (Result <> 0) and ControlViewInfo.Visible{(AWidth <> 0)} then
Inc(Result, ControlOffsetHorz);
Inc(Result, AWidth);
end;
clTop, clBottom:
Result := Max(Result, AWidth);
else
Result := 0;
end;
Inc(Result, inherited DoCalculateWidth(AIsMinWidth));
end;
function TdxLayoutItemViewInfo.GetAutoControlAlignment: Boolean;
function AreAlignmentAndCaptionLayoutLinked: Boolean;
begin
case CaptionLayout of
clLeft:
Result := AlignHorz in [ahLeft, ahClient];
clTop:
Result := AlignVert in [avTop, avClient];
clRight:
Result := AlignHorz in [ahRight, ahClient];
clBottom:
Result := AlignVert in [avBottom, avClient];
else
Result := False;
end;
end;
begin
Result :=
Item.ControlOptions.AutoAlignment and HasCaption and HasControl and
AreAlignmentAndCaptionLayoutLinked;
end;
function TdxLayoutItemViewInfo.GetCaptionLayout: TdxCaptionLayout;
begin
Result := Item.CaptionOptions.Layout;
end;
function TdxLayoutItemViewInfo.GetColor: TColor;
begin
if ParentViewInfo <> nil then // for dragging
Result := ParentViewInfo.GetColor
else
Result := ContainerViewInfo.ItemsViewInfo.GetColor;
end;
function TdxLayoutItemViewInfo.GetContentBounds: TRect;
begin
Result := Bounds;
end;
function TdxLayoutItemViewInfo.GetControlOffsetHorz: Integer;
begin
Result := LayoutLookAndFeel.GetControlOffsetHorz(Item.Container);
end;
function TdxLayoutItemViewInfo.GetControlOffsetVert: Integer;
begin
Result := LayoutLookAndFeel.GetControlOffsetVert(Item.Container);
end;
function TdxLayoutItemViewInfo.GetIsDefaultColor: Boolean;
begin
Result := ParentViewInfo.IsDefaultColor;
end;
function TdxLayoutItemViewInfo.GetOptions: TdxCustomLayoutLookAndFeelOptions;
begin
Result := LayoutLookAndFeel.ItemOptions;
end;
function TdxLayoutItemViewInfo.HasControl: Boolean;
begin
Result := Item.HasControl;
end;
procedure TdxLayoutItemViewInfo.PaintSelectionLayer;
begin
inherited;
if HasControl and ActuallyVisible and IsParentSelected and not Selected then
ContainerViewInfo.SelectionLayer.SelectionImage.cxCanvas.FillRect(ControlViewInfo.Bounds, 0);
end;
function TdxLayoutItemViewInfo.PtInDesignSelectorRect(const P: TPoint): Boolean;
begin
Result := PtInRect(DesignSelectorRect, P);
end;
procedure TdxLayoutItemViewInfo.Calculate(const ABounds: TRect);
var
ACaptionViewInfoBounds, AControlViewInfoBounds: TRect;
begin
inherited;
CalculateViewInfosBounds(ACaptionViewInfoBounds, AControlViewInfoBounds);
CaptionViewInfo.Calculate(ACaptionViewInfoBounds);
ControlViewInfo.Calculate(AControlViewInfoBounds);
Item.UpdateDesignSelectors;
end;
procedure TdxLayoutItemViewInfo.CalculateTabOrders(var AAvailTabOrder: Integer);
begin
ControlViewInfo.CalculateTabOrder(AAvailTabOrder);
end;
{ TdxLayoutGroupCaptionViewInfo }
function TdxLayoutGroupCaptionViewInfo.GetAlignVert: TdxAlignmentVert;
begin
Result := tavTop;
end;
function TdxLayoutGroupCaptionViewInfo.GetMultiLine: Boolean;
begin
Result := False;
end;
function TdxLayoutGroupCaptionViewInfo.CalculateMinWidth: Integer;
begin
Result := CalculateWidth;
end;
{ TdxLayoutGroupViewInfoSpecific }
constructor TdxLayoutGroupViewInfoSpecific.Create(AGroupViewInfo: TdxLayoutGroupViewInfo);
begin
inherited Create;
FGroupViewInfo := AGroupViewInfo;
CreateSpecificControls;
end;
destructor TdxLayoutGroupViewInfoSpecific.Destroy;
begin
DestroySpecificControls;
inherited Destroy;
end;
procedure TdxLayoutGroupViewInfoSpecific.Calculate(const AItemsAreaBounds: TRect);
begin
CalculateItemsBounds(AItemsAreaBounds);
end;
procedure TdxLayoutGroupViewInfoSpecific.PrepareItemInfos;
var
I: Integer;
begin
SetLength(FItemInfos, ItemViewInfoCount);
for I := 0 to ItemViewInfoCount - 1 do
begin
FItemInfos[I].ViewInfo := ItemViewInfos[I];
FItemInfos[I].AlignHorz := GetItemAlignHorz(FItemInfos[I].ViewInfo);
FItemInfos[I].CalculatedWidth := GetItemWidth(FItemInfos[I].ViewInfo);
FItemInfos[I].Height := GetItemHeight(FItemInfos[I].ViewInfo);
FItemInfos[I].MinWidth := GetItemMinWidth(FItemInfos[I].ViewInfo);
FItemInfos[I].Calculated := False;
end;
end;
procedure TdxLayoutGroupViewInfoSpecific.CalculateItemsHorizontalBounds(const AItemsAreaBounds: TRect);
var
ASpace, AAvailableSpace: Integer;
procedure CalculateSpaces;
var
AItemOffsets, I: Integer;
AIsFirstItem: Boolean;
begin
AItemOffsets := 0;
ASpace := 0;
AIsFirstItem := True;
for I := 0 to ItemViewInfoCount - 1 do
if FItemInfos[I].AlignHorz <> ahCenter then
begin
if not AIsFirstItem then
Inc(AItemOffsets, ItemOffset);
Inc(ASpace, FItemInfos[I].CalculatedWidth);
AIsFirstItem := False;
end;
AAvailableSpace := cxRectWidth(AItemsAreaBounds) - AItemOffsets;
end;
procedure InternalCalculateItemsVisibleSizes;
procedure CalculateNonClientAlignedItemsVisibleSizes;
var
I: Integer;
begin
for I := 0 to ItemViewInfoCount - 1 do
if FItemInfos[I].AlignHorz <> ahClient then
begin
FItemInfos[I].Width := FItemInfos[I].CalculatedWidth;
if FItemInfos[I].AlignHorz <> ahCenter then
begin
Dec(ASpace, FItemInfos[I].Width);
Dec(AAvailableSpace, FItemInfos[I].Width);
end;
FItemInfos[I].Calculated := True;
end;
end;
procedure CalculateClientAlignedItemsVisibleSizes;
var
ANeedRecalculating: Boolean;
ANextSpace, ANextAvailableSpace, I: Integer;
begin
repeat
ANeedRecalculating := False;
ANextSpace := ASpace;
ANextAvailableSpace := AAvailableSpace;
for I := 0 to ItemViewInfoCount - 1 do
if not FItemInfos[I].Calculated then
begin
FItemInfos[I].Width := MulDiv(AAvailableSpace, FItemInfos[I].CalculatedWidth, ASpace);
if FItemInfos[I].Width < FItemInfos[I].MinWidth then
begin
FItemInfos[I].Width := FItemInfos[I].MinWidth;
Dec(ANextSpace, FItemInfos[I].CalculatedWidth);
Dec(ANextAvailableSpace, FItemInfos[I].Width);
FItemInfos[I].Calculated := True;
ANeedRecalculating := True;
end;
end;
ASpace := ANextSpace;
AAvailableSpace := ANextAvailableSpace;
until not ANeedRecalculating;
end;
begin
CalculateNonClientAlignedItemsVisibleSizes;
CalculateClientAlignedItemsVisibleSizes;
end;
procedure InternalCalculateItemsBounds;
procedure CalculateLeftAlignedItemsBounds;
var
AOffset, I: Integer;
begin
AOffset := AItemsAreaBounds.Left;
for I := 0 to ItemViewInfoCount - 1 do
with FItemInfos[I] do
case AlignHorz of
ahLeft, ahClient:
begin
Bounds.Left := AOffset;
Bounds.Right := AOffset + Width;
Inc(AOffset, Width + ItemOffset);
end;
ahCenter:
begin
Bounds.Left := (AItemsAreaBounds.Left + AItemsAreaBounds.Right - Width) div 2;
Bounds.Right := Bounds.Left + Width;
end;
end;
end;
procedure CalculateRightAlignedItemsBounds;
var
AOffset, I: Integer;
begin
AOffset := AItemsAreaBounds.Right;
for I := ItemViewInfoCount - 1 downto 0 do
with FItemInfos[I] do
if AlignHorz = ahRight then
begin
Bounds.Right := AOffset;
Bounds.Left := AOffset - Width;
Dec(AOffset, Width + ItemOffset);
end;
end;
begin
CalculateLeftAlignedItemsBounds;
CalculateRightAlignedItemsBounds;
end;
begin
CalculateSpaces;
InternalCalculateItemsVisibleSizes;
InternalCalculateItemsBounds;
end;
procedure TdxLayoutGroupViewInfoSpecific.CalculateItemsVerticalBounds(const AItemsAreaBounds: TRect);
var
I: Integer;
begin
for I := 0 to ItemViewInfoCount - 1 do
with FItemInfos[I] do
case GetItemAlignVert(ViewInfo) of
avTop:
begin
Bounds.Top := AItemsAreaBounds.Top;
Bounds.Bottom := Bounds.Top + Height;
end;
avCenter:
begin
Bounds.Top := (AItemsAreaBounds.Top + AItemsAreaBounds.Bottom - Height) div 2;
Bounds.Bottom := Bounds.Top + Height;
end;
avBottom:
begin
Bounds.Bottom := AItemsAreaBounds.Bottom;
Bounds.Top := Bounds.Bottom - Height;
end;
avClient:
begin
Bounds.Top := AItemsAreaBounds.Top;
Bounds.Bottom := AItemsAreaBounds.Bottom;
end;
end;
end;
procedure TdxLayoutGroupViewInfoSpecific.CalculateTabOrders(var ATabOrder: Integer);
begin
// do nothing
end;
procedure TdxLayoutGroupViewInfoSpecific.CalculateItemViewInfos;
var
I: Integer;
begin
for I := 0 to ItemViewInfoCount - 1 do
begin
ConvertCoords(FItemInfos[I].Bounds);
FItemInfos[I].ViewInfo.Calculate(FItemInfos[I].Bounds);
end;
end;
function TdxLayoutGroupViewInfoSpecific.GetContainer: TdxCustomLayoutControl;
begin
Result := GroupViewInfo.ContainerViewInfo.Control;
end;
function TdxLayoutGroupViewInfoSpecific.GetItemOffset: Integer;
begin
Result := FGroupViewInfo.ItemOffset;
end;
function TdxLayoutGroupViewInfoSpecific.GetItemViewInfo(Index: Integer): TdxCustomLayoutItemViewInfo;
begin
Result := FGroupViewInfo.ItemViewInfos[Index];
end;
function TdxLayoutGroupViewInfoSpecific.GetItemViewInfoCount: Integer;
begin
Result := FGroupViewInfo.ItemViewInfoCount;
end;
function TdxLayoutGroupViewInfoSpecific.GetLayoutDirection: TdxLayoutDirection;
begin
Result := FGroupViewInfo.LayoutDirection;
end;
procedure TdxLayoutGroupViewInfoSpecific.CreateSpecificControls;
begin
// do nothing
end;
procedure TdxLayoutGroupViewInfoSpecific.DestroySpecificControls;
begin
// do nothing
end;
procedure TdxLayoutGroupViewInfoSpecific.CreateViewInfos;
begin
// do nothing
end;
procedure TdxLayoutGroupViewInfoSpecific.SetControlVisibility;
begin
// do nothing
end;
procedure TdxLayoutGroupViewInfoSpecific.AddSelectionControls;
begin
// do nothing
end;
procedure TdxLayoutGroupViewInfoSpecific.RemoveSelectionControls;
begin
// do nothing
end;
procedure TdxLayoutGroupViewInfoSpecific.DrawSpecificPart(ACanvas: TcxCanvas);
begin
// do nothing
end;
procedure TdxLayoutGroupViewInfoSpecific.DrawSpecificBackground(ACanvas: TcxCanvas);
begin
if GroupViewInfo.HasBackground then
ACanvas.FillRect(GroupViewInfo.BackgroundBounds, GroupViewInfo.GetBackgroundColor);
end;
function TdxLayoutGroupViewInfoSpecific.GetCustomHeight(AIsMinHeight: Boolean): Integer;
var
I: Integer;
begin
Result := 0;
for I := 0 to ItemViewInfoCount - 1 do
if AIsMinHeight then
Result := Max(Result, GetItemMinHeight(ItemViewInfos[I]))
else
Result := Max(Result, GetItemHeight(ItemViewInfos[I]))
end;
function TdxLayoutGroupViewInfoSpecific.GetCustomWidth(AIsMinWidth: Boolean): Integer;
var
AIsFirstItem: Boolean;
I: Integer;
AItemViewInfo: TdxCustomLayoutItemViewInfo;
begin
Result := 0;
AIsFirstItem := True;
for I := 0 to ItemViewInfoCount - 1 do
begin
AItemViewInfo := ItemViewInfos[I];
if GetItemAlignHorz(AItemViewInfo) <> ahCenter then
begin
if not AIsFirstItem then
Inc(Result, ItemOffset);
if AIsMinWidth then
Inc(Result, GetItemMinWidth(AItemViewInfo))
else
Inc(Result, GetItemWidth(AItemViewInfo));
AIsFirstItem := False;
end;
end;
for I := 0 to ItemViewInfoCount - 1 do
begin
AItemViewInfo := ItemViewInfos[I];
if GetItemAlignHorz(AItemViewInfo) = ahCenter then
if AIsMinWidth then
Result := Max(Result, GetItemMinWidth(AItemViewInfo))
else
Result := Max(Result, GetItemWidth(AItemViewInfo))
end;
end;
function TdxLayoutGroupViewInfoSpecific.GetAreaPart(const P: TPoint): TdxLayoutAreaPart;
begin
Result := apNone;
if (GroupViewInfo.Group.VisibleCount = 0) and PtInRect(dxGetCenterAreaBounds(GroupViewInfo.Bounds), P) then
Result := apCenter;
end;
function TdxLayoutGroupViewInfoSpecific.GetHitTest(const P: TPoint): TdxCustomLayoutHitTest;
begin
Result := nil;
end;
function TdxLayoutGroupViewInfoSpecific.GetItemsAreaOffset(ASide: TdxLayoutSide): Integer;
begin
Result := 0;
end;
procedure TdxLayoutGroupViewInfoSpecific.ConvertCoords(var R: TRect);
begin
end;
procedure TdxLayoutGroupViewInfoSpecific.CalculateItemsBounds(AItemsAreaBounds: TRect);
begin
ConvertCoords(AItemsAreaBounds);
PrepareItemInfos;
CalculateItemsHorizontalBounds(AItemsAreaBounds);
CalculateItemsVerticalBounds(AItemsAreaBounds);
CalculateItemViewInfos;
end;
function TdxLayoutGroupViewInfoSpecific.CanDrawBackground: Boolean;
begin
Result := False;
end;
function TdxLayoutGroupViewInfoSpecific.GetItemsAreaHeight(AIsMinHeight: Boolean): Integer;
begin
Result := GetCustomHeight(AIsMinHeight);
end;
function TdxLayoutGroupViewInfoSpecific.GetItemsAreaWidth(AIsMinWidth: Boolean): Integer;
begin
Result := GetCustomWidth(AIsMinWidth);
end;
function TdxLayoutGroupViewInfoSpecific.AllowDrawChild(AChild: TdxCustomLayoutItem): Boolean;
begin
Result := True;
end;
function TdxLayoutGroupViewInfoSpecific.AllowChildHasBorder: Boolean;
begin
Result := True;
end;
{ TdxLayoutGroupHorizontalSpecific }
function TdxLayoutGroupViewInfoHorizontalSpecific.GetItemAlignHorz(AViewInfo: TdxCustomLayoutItemViewInfo): TdxLayoutAlignHorz;
begin
Result := AViewInfo.AlignHorz;
end;
function TdxLayoutGroupViewInfoHorizontalSpecific.GetItemAlignVert(AViewInfo: TdxCustomLayoutItemViewInfo): TdxLayoutAlignVert;
begin
Result := AViewInfo.AlignVert;
end;
function TdxLayoutGroupViewInfoHorizontalSpecific.GetItemHeight(AViewInfo: TdxCustomLayoutItemViewInfo): Integer;
begin
Result := AViewInfo.Height;
end;
function TdxLayoutGroupViewInfoHorizontalSpecific.GetItemWidth(AViewInfo: TdxCustomLayoutItemViewInfo): Integer;
begin
Result := AViewInfo.Width;
end;
function TdxLayoutGroupViewInfoHorizontalSpecific.GetItemMinHeight(AViewInfo: TdxCustomLayoutItemViewInfo): Integer;
begin
Result := AViewInfo.MinHeight;
end;
function TdxLayoutGroupViewInfoHorizontalSpecific.GetItemMinWidth(AViewInfo: TdxCustomLayoutItemViewInfo): Integer;
begin
Result := AViewInfo.MinWidth;
end;
function TdxLayoutGroupViewInfoHorizontalSpecific.IsAtInsertionPos(const R: TRect;
const P: TPoint): Boolean;
begin
Result := P.X < (R.Left + R.Right) div 2;
end;
{ TdxLayoutGroupViewInfoVerticalSpecific }
procedure TdxLayoutGroupViewInfoVerticalSpecific.ConvertCoords(var R: TRect);
begin
ExchangeLongWords(R.Left, R.Top);
ExchangeLongWords(R.Right, R.Bottom);
end;
function TdxLayoutGroupViewInfoVerticalSpecific.GetItemAlignHorz(AViewInfo: TdxCustomLayoutItemViewInfo): TdxLayoutAlignHorz;
begin
Result := TdxLayoutAlignHorz(AViewInfo.AlignVert);
end;
function TdxLayoutGroupViewInfoVerticalSpecific.GetItemAlignVert(AViewInfo: TdxCustomLayoutItemViewInfo): TdxLayoutAlignVert;
begin
Result := TdxLayoutAlignVert(AViewInfo.AlignHorz);
end;
function TdxLayoutGroupViewInfoVerticalSpecific.GetItemHeight(AViewInfo: TdxCustomLayoutItemViewInfo): Integer;
begin
Result := AViewInfo.GetWidth;
end;
function TdxLayoutGroupViewInfoVerticalSpecific.GetItemWidth(AViewInfo: TdxCustomLayoutItemViewInfo): Integer;
begin
Result := AViewInfo.GetHeight;
end;
function TdxLayoutGroupViewInfoVerticalSpecific.GetItemMinHeight(AViewInfo: TdxCustomLayoutItemViewInfo): Integer;
begin
Result := AViewInfo.MinWidth;
end;
function TdxLayoutGroupViewInfoVerticalSpecific.GetItemMinWidth(AViewInfo: TdxCustomLayoutItemViewInfo): Integer;
begin
Result := AViewInfo.MinHeight;
end;
function TdxLayoutGroupViewInfoVerticalSpecific.GetItemsAreaHeight(AIsMinHeight: Boolean): Integer;
begin
Result := inherited GetItemsAreaWidth(AIsMinHeight);
end;
function TdxLayoutGroupViewInfoVerticalSpecific.GetItemsAreaWidth(AIsMinWidth: Boolean): Integer;
begin
Result := inherited GetItemsAreaHeight(AIsMinWidth);
end;
function TdxLayoutGroupViewInfoVerticalSpecific.IsAtInsertionPos(const R: TRect;
const P: TPoint): Boolean;
begin
Result := P.Y < (R.Top + R.Bottom) div 2;
end;
{ TdxLayoutTabbedGroupTabControl }
procedure TdxLayoutTabbedGroupTabControl.BoundsChanged;
var
ARegion: TcxRegion;
begin
inherited;
if HandleAllocated then
begin
ARegion := TcxRegion.Create(Bounds);
try
ARegion.Combine(TcxRegion.Create(DisplayRect), roSubtract);
SetWindowRgn(Handle, ARegion.Handle, False);
finally
ARegion.Free;
end;
end;
end;
function TdxLayoutTabbedGroupTabControl.GetDesignHitTest(X, Y: Integer; Shift: TShiftState): Boolean;
begin
Result := True;
end;
procedure TdxLayoutTabbedGroupTabControl.WMNCHitTest(var Message: TWMNCHitTest);
begin
Message.Result := HTTRANSPARENT;
end;
{ TdxTabControlElementViewInfo }
function TdxTabControlElementViewInfo.GetVisible: Boolean;
begin
Result := not cxRectIsEmpty(Bounds);
end;
procedure TdxTabControlElementViewInfo.MouseEnter;
begin
FTabControl.MouseEnter(nil);
end;
procedure TdxTabControlElementViewInfo.MouseLeave;
begin
FTabControl.MouseLeave(nil);
end;
procedure TdxTabControlElementViewInfo.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
FTabControl.MouseDown(Button, Shift, X - FTabControl.Left, Y - FTabControl.Top);
end;
procedure TdxTabControlElementViewInfo.MouseMove(Shift: TShiftState; X, Y: Integer);
var
ATabIndex: Integer;
AClientPoint: TPoint;
begin
FTabControl.MouseMove(Shift, X - FTabControl.Left, Y - FTabControl.Top);
if ItemViewInfo.ContainerViewInfo.Control.DragAndDropState <> ddsNone then
begin
AClientPoint := cxPointOffset(Point(X, Y), Point(FTabControl.Left, FTabControl.Top), False);
ATabIndex := FTabControl.IndexOfTabAt(AClientPoint.X, AClientPoint.Y);
if ATabIndex <> -1 then
FTabControl.TabIndex := ATabIndex;
end;
end;
procedure TdxTabControlElementViewInfo.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
FTabControl.MouseUp(Button, Shift, X - FTabControl.Left, Y - FTabControl.Top);
end;
{ TdxLayoutGroupViewInfoTabbedSpecific }
procedure TdxLayoutGroupViewInfoTabbedSpecific.Calculate(const AItemsAreaBounds: TRect);
var
ARect: TRect;
begin
inherited;
if HasTabControl then
begin
FTabControl.BoundsRect := GroupViewInfo.ClientBounds;
FTabControl.Parent := Container;
ARect := GroupViewInfo.ClientBounds;
ARect.Bottom := GroupViewInfo.ItemsAreaBounds.Top;
FTabControlElementViewInfo.Calculate(ARect);
FTabControlElementViewInfo.FTabControl := FTabControl;
end
else
FTabControlElementViewInfo.Calculate(cxEmptyRect);
end;
function TdxLayoutGroupViewInfoTabbedSpecific.AllowDrawChild(AChild: TdxCustomLayoutItem): Boolean;
begin
Result := inherited AllowDrawChild(AChild) and (AChild.VisibleIndex = GroupViewInfo.Group.ItemIndex);
end;
function TdxLayoutGroupViewInfoTabbedSpecific.AllowChildHasBorder: Boolean;
begin
Result := False;
end;
function TdxLayoutGroupViewInfoTabbedSpecific.CanDrawBackground: Boolean;
begin
Result := True;
end;
procedure TdxLayoutGroupViewInfoTabbedSpecific.CalculateItemsHorizontalBounds(const AItemsAreaBounds: TRect);
var
I: Integer;
begin
for I := 0 to ItemViewInfoCount - 1 do
with FItemInfos[I] do
begin
Width := CalculatedWidth;
case GetItemAlignHorz(ViewInfo) of
ahLeft:
begin
Bounds.Left := AItemsAreaBounds.Left;
Bounds.Right := Bounds.Left + Width;
end;
ahCenter:
begin
Bounds.Left := (AItemsAreaBounds.Left + AItemsAreaBounds.Right - Width) div 2;
Bounds.Right := Bounds.Left + Width;
end;
ahRight:
begin
Bounds.Right := AItemsAreaBounds.Right;
Bounds.Left := Bounds.Right - Width;
end;
ahClient:
begin
Bounds.Left := AItemsAreaBounds.Left;
Bounds.Right := AItemsAreaBounds.Right;
end;
end;
end;
end;
procedure TdxLayoutGroupViewInfoTabbedSpecific.CalculateItemsVerticalBounds(const AItemsAreaBounds: TRect);
begin
inherited;
end;
procedure TdxLayoutGroupViewInfoTabbedSpecific.CalculateTabOrders(var ATabOrder: Integer);
begin
if HasTabControl then
begin
FTabControl.TabOrder := ATabOrder;
Inc(ATabOrder);
end;
end;
function TdxLayoutGroupViewInfoTabbedSpecific.GetAreaPart(const P: TPoint): TdxLayoutAreaPart;
begin
if HasTabControl and PtInRect(FTabControl.BoundsRect, P) then
Result := apCenter
else
Result := inherited GetAreaPart(P);
end;
function TdxLayoutGroupViewInfoTabbedSpecific.GetHitTest(const P: TPoint): TdxCustomLayoutHitTest;
var
ATabIndex: Integer;
AClientPoint: TPoint;
begin
Result := nil;
if HasTabControl then
begin
AClientPoint := cxPointOffset(P, Point(FTabControl.Left, FTabControl.Top), False);
ATabIndex := FTabControl.IndexOfTabAt(AClientPoint.X, AClientPoint.Y);
if ATabIndex <> -1 then
Result := GroupViewInfo.ItemViewInfos[ATabIndex].CreateHitTest;
end;
end;
procedure TdxLayoutGroupViewInfoTabbedSpecific.DrawSpecificPart(ACanvas: TcxCanvas);
var
ARegion: TcxRegion;
begin
inherited DrawSpecificPart(ACanvas);
if HasTabControl then
begin
ACanvas.SaveState;
try
with FTabControl.BoundsRect.TopLeft do
MoveWindowOrg(ACanvas.Handle, X, Y);
ARegion := TcxRegion.Create;
try
GetWindowRgn(FTabControl.Handle, ARegion.Handle);
ACanvas.SetClipRegion(ARegion, roIntersect, False);
finally
ARegion.Free;
end;
FTabControl.PaintTo(ACanvas.Handle, 0, 0);
finally
ACanvas.RestoreState;
end;
end;
end;
procedure TdxLayoutGroupViewInfoTabbedSpecific.DrawSpecificBackground(ACanvas: TcxCanvas);
begin
if not HasTabControl or (csPaintCopy in (FTabControl.ControlState + Container.ControlState)) then
inherited
else
begin
ACanvas.SaveState;
try
with FTabControl.BoundsRect.TopLeft do
MoveWindowOrg(ACanvas.Handle, X, Y);
ACanvas.IntersectClipRect(FTabControl.DisplayRect);
FTabControl.PaintTo(ACanvas.Canvas, 0, 0);
finally
ACanvas.RestoreState;
end;
end;
end;
function TdxLayoutGroupViewInfoTabbedSpecific.GetCustomHeight(AIsMinHeight: Boolean): Integer;
begin
Result := inherited GetCustomHeight(AIsMinHeight);
end;
function TdxLayoutGroupViewInfoTabbedSpecific.GetCustomWidth(AIsMinWidth: Boolean): Integer;
var
I: Integer;
begin
Result := 0;
for I := 0 to ItemViewInfoCount - 1 do
if AIsMinWidth then
Result := Max(Result, GetItemMinWidth(ItemViewInfos[I]))
else
Result := Max(Result, GetItemWidth(ItemViewInfos[I]))
end;
function TdxLayoutGroupViewInfoTabbedSpecific.GetItemsAreaOffset(ASide: TdxLayoutSide): Integer;
begin
Result := inherited GetItemsAreaOffset(ASide);
// #DG !!!
if HasTabControl then
begin
Inc(Result, GroupViewInfo.LayoutLookAndFeel.GetItemsAreaOffset(GroupViewInfo.Group.Container));
case ASide of
sdLeft: Inc(Result, TcxPCCustomPainterAccess(FTabControl.Painter).GetClientRectOffset.Left);
sdRight: Inc(Result, TcxPCCustomPainterAccess(FTabControl.Painter).GetClientRectOffset.Right);
sdTop: Inc(Result, TcxPCCustomPainterAccess(FTabControl.Painter).GetClientRectOffset.Top);
sdBottom: Inc(Result, TcxPCCustomPainterAccess(FTabControl.Painter).GetClientRectOffset.Bottom);
end;
end;
end;
procedure TdxLayoutGroupViewInfoTabbedSpecific.CreateSpecificControls;
begin
inherited CreateSpecificControls;
CreateTabControl;
end;
procedure TdxLayoutGroupViewInfoTabbedSpecific.DestroySpecificControls;
begin
inherited DestroySpecificControls;
DestroyTabControl;
end;
procedure TdxLayoutGroupViewInfoTabbedSpecific.CreateViewInfos;
begin
FTabControlElementViewInfo := TdxTabControlElementViewInfo.Create(GroupViewInfo);
GroupViewInfo.FElements.Add(FTabControlElementViewInfo);
end;
procedure TdxLayoutGroupViewInfoTabbedSpecific.SetControlVisibility;
begin
if HasTabControl then
FTabControl.Visible := GroupViewInfo.ActuallyVisible;
end;
procedure TdxLayoutGroupViewInfoTabbedSpecific.CreateTabControl;
var
I: Integer;
begin
if GroupViewInfo.Group.VisibleCount = 0 then
Exit;
FTabControl := TdxLayoutTabbedGroupTabControl.Create(GroupViewInfo.Group);
FTabControl.Font := Container.Font;
for I := 0 to GroupViewInfo.Group.VisibleCount - 1 do
FTabControl.Tabs.Add(GroupViewInfo.Group.VisibleItems[I].Caption);
FTabControl.TabIndex := GroupViewInfo.Group.ItemIndex;
GroupViewInfo.LayoutLookAndFeel.InitializeSubControlCxLookAndFeel(FTabControl.LookAndFeel);
FTabControl.OnChange := ActiveTabChanged;
end;
procedure TdxLayoutGroupViewInfoTabbedSpecific.DestroyTabControl;
begin
FreeAndNil(FTabControl);
end;
function TdxLayoutGroupViewInfoTabbedSpecific.HasTabControl: Boolean;
begin
Result := FTabControl <> nil;
end;
procedure TdxLayoutGroupViewInfoTabbedSpecific.ActiveTabChanged(ASender: TObject);
var
AContainer: TdxCustomLayoutControl;
begin
AContainer := GroupViewInfo.Group.Container;
GroupViewInfo.Group.ItemIndex := FTabControl.TabIndex;
AContainer.Modified;
end;
{ TdxLayoutGroupViewInfo }
function TdxLayoutGroupViewInfo.GetBorderBounds(ASide: TdxLayoutSide): TRect;
begin
Result := Bounds;
with ClientBounds do
case ASide of
sdLeft:
Result.Right := Left;
sdTop:
Result.Bottom := Top;
sdRight:
Result.Left := Right;
sdBottom:
Result.Top := Bottom;
end;
end;
function TdxLayoutGroupViewInfo.GetBorderRestSpaceBounds(ASide: TdxLayoutSide): TRect;
begin
Result := RestSpaceBounds;
with ClientBounds do
case ASide of
sdLeft:
Result.Right := Left;
sdTop:
Result.Bottom := Top;
sdRight:
Result.Left := Right;
sdBottom:
Result.Top := Bottom;
end;
end;
function TdxLayoutGroupViewInfo.GetBordersHeight: Integer;
begin
Result := BorderWidths[sdLeft] + BorderWidths[sdRight];
end;
function TdxLayoutGroupViewInfo.GetBordersWidth: Integer;
begin
Result := BorderWidths[sdTop] + BorderWidths[sdBottom];
end;
function TdxLayoutGroupViewInfo.GetCaptionViewInfo: TdxLayoutGroupCaptionViewInfo;
begin
Result := TdxLayoutGroupCaptionViewInfo(inherited CaptionViewInfo);
end;
function TdxLayoutGroupViewInfo.GetGroup: TdxLayoutGroup;
begin
Result := TdxLayoutGroup(inherited Item);
end;
function TdxLayoutGroupViewInfo.GetIsLocked: Boolean;
begin
Result := Group.Locked and IsCustomization or IsParentLocked;
end;
function TdxLayoutGroupViewInfo.GetItemViewInfo(Index: Integer): TdxCustomLayoutItemViewInfo;
begin
Result := TdxCustomLayoutItemViewInfo(FItemViewInfos[Index]);
end;
function TdxLayoutGroupViewInfo.GetItemViewInfoCount: Integer;
begin
Result := FItemViewInfos.Count;
end;
function TdxLayoutGroupViewInfo.GetLayoutDirection: TdxLayoutDirection;
begin
Result := Group.LayoutDirection;
end;
function TdxLayoutGroupViewInfo.GetOptionsEx: TdxLayoutLookAndFeelGroupOptions;
begin
Result := TdxLayoutLookAndFeelGroupOptions(inherited Options);
end;
function TdxLayoutGroupViewInfo.GetOffset(Index: Integer): Integer;
begin
if not FOffsetsCalculated then
begin
CalculateOffsets;
FOffsetsCalculated := True;
end;
case Index of
0: Result := FItemOffset;
1: Result := FItemsAreaOffsetHorz;
2: Result := FItemsAreaOffsetVert;
else
Result := -1;
end;
end;
procedure TdxLayoutGroupViewInfo.CreateItemViewInfos;
var
I: Integer;
AItem: TdxCustomLayoutItem;
AItemViewInfo: TdxCustomLayoutItemViewInfo;
begin
FItemViewInfos := TObjectList.Create;
for I := 0 to Group.Count - 1 do
begin
AItem := Group.Items[I];
if AItem.GetVisible or (IsDragImagePainted and IsAvailable) then
begin
AItemViewInfo := GetItemViewInfoClass(AItem).Create(FContainerViewInfo, Self, AItem);
FItemViewInfos.Add(AItemViewInfo);
end;
end;
end;
procedure TdxLayoutGroupViewInfo.CreateSpecific;
begin
FSpecific := GetSpecificClass.Create(Self);
end;
procedure TdxLayoutGroupViewInfo.DestroyItemViewInfos;
begin
FreeAndNil(FItemViewInfos);
end;
procedure TdxLayoutGroupViewInfo.DestroySpecific;
begin
FreeAndNil(FSpecific);
end;
function TdxLayoutGroupViewInfo.GetClientAreaBounds(const ABounds: TRect): TRect;
var
AMargins: TRect;
begin
with LayoutLookAndFeel do
AMargins := Rect(GetBorderWidth(sdLeft), GetBorderWidth(sdTop), GetBorderWidth(sdRight), GetBorderWidth(sdBottom));
Result := cxRectContent(ABounds, AMargins);
end;
function TdxLayoutGroupViewInfo.GetItemAreaBounds(const AClientRect: TRect): TRect;
var
AMargins: TRect;
begin
with LayoutLookAndFeel do
AMargins := Rect(GetBorderWidth(sdLeft), GetBorderWidth(sdTop), GetBorderWidth(sdRight), GetBorderWidth(sdBottom));
Result := cxRectInflate(AClientRect, AMargins);
end;
function TdxLayoutGroupViewInfo.GetBackgroundColor: TColor;
begin
if Group.IsRoot and ContainerViewInfo.NeedHighlightRoot then
Result := dxLayoutHiddenGroupBackgroundDefaultColor
else
Result := inherited GetBackgroundColor;
end;
procedure TdxLayoutGroupViewInfo.DoCreateViewInfos;
begin
inherited;
CreateSpecific;
CreateItemViewInfos;
Specific.CreateViewInfos;
end;
procedure TdxLayoutGroupViewInfo.DestroyViewInfos;
begin
DestroyItemViewInfos;
DestroySpecific;
inherited;
end;
procedure TdxLayoutGroupViewInfo.FreeNotification(AComponent: TComponent);
begin
inherited;
Specific.DestroySpecificControls;
end;
function TdxLayoutGroupViewInfo.GetCaptionViewInfoClass: TdxCustomLayoutItemCaptionViewInfoClass;
begin
Result := TdxLayoutGroupCaptionViewInfo;
end;
function TdxLayoutGroupViewInfo.GetHitTestClass: TdxCustomLayoutItemHitTestClass;
begin
Result := TdxLayoutGroupHitTest;
end;
function TdxLayoutGroupViewInfo.GetPainterClass: TdxCustomLayoutItemPainterClass;
begin
Result := TdxCustomLayoutItemPainterClass(LayoutLookAndFeel.GetGroupPainterClass);
end;
function TdxLayoutGroupViewInfo.DoCalculateHeight(AIsMinHeight: Boolean = False): Integer;
begin
Result := inherited DoCalculateHeight(AIsMinHeight) + GetHeight(Specific.GetItemsAreaHeight(AIsMinHeight));
end;
function TdxLayoutGroupViewInfo.DoCalculateWidth(AIsMinWidth: Boolean = False): Integer;
begin
Result := inherited DoCalculateWidth(AIsMinWidth) + GetWidth(Specific.GetItemsAreaWidth(AIsMinWidth));
end;
function TdxLayoutGroupViewInfo.GetAreaPart(const P: TPoint): TdxLayoutAreaPart;
begin
Result := Specific.GetAreaPart(P);
if Result = apNone then
Result := inherited GetAreaPart(P);
end;
function TdxLayoutGroupViewInfo.HasCaption: Boolean;
begin
Result := inherited HasCaption and HasBorder;
end;
function TdxLayoutGroupViewInfo.HasBorder: Boolean;
begin
Result := Group.ShowBorder and ((ParentViewInfo = nil) or
ParentViewInfo.AllowChildHasBorder or IsDragImagePainted and IsDragged);
end;
procedure TdxLayoutGroupViewInfo.CalculateCaptionViewInfoBounds;
begin
FCaptionAreaBounds := cxNullRect;
end;
procedure TdxLayoutGroupViewInfo.CalculateClientBounds;
begin
FClientAreaBounds := GetClientAreaBounds(FBounds);
end;
procedure TdxLayoutGroupViewInfo.CalculateItemsAreaBounds;
begin
FItemsAreaBounds := cxRectInflate(ClientBounds, -ItemsAreaOffsetHorz, -ItemsAreaOffsetVert);
Inc(FItemsAreaBounds.Left, Specific.GetItemsAreaOffset(sdLeft));
Dec(FItemsAreaBounds.Right, Specific.GetItemsAreaOffset(sdRight));
Inc(FItemsAreaBounds.Top, Specific.GetItemsAreaOffset(sdTop));
Dec(FItemsAreaBounds.Bottom, Specific.GetItemsAreaOffset(sdBottom));
end;
procedure TdxLayoutGroupViewInfo.CalculateOffsets;
begin
if UseItemsAreaOffsets then
if Group.IsRoot then
begin
ItemsAreaOffsetHorz := LayoutLookAndFeel.GetRootItemsAreaOffsetHorz(Item.Container);
ItemsAreaOffsetVert := LayoutLookAndFeel.GetRootItemsAreaOffsetVert(Item.Container);
end
else
begin
ItemsAreaOffsetHorz := LayoutLookAndFeel.GetItemsAreaOffsetHorz(Item.Container);
ItemsAreaOffsetVert := LayoutLookAndFeel.GetItemsAreaOffsetVert(Item.Container);
end
else
begin
ItemsAreaOffsetHorz := 0;
ItemsAreaOffsetVert := 0;
end;
if UseItemOffset then
ItemOffset := LayoutLookAndFeel.GetItemOffset(Item.Container)
else
ItemOffset := 0;
end;
function TdxLayoutGroupViewInfo.GetBorderWidth(ASide: TdxLayoutSide): Integer;
begin
//#DG !!!
if HasBorder then
Result := LayoutLookAndFeel.GetGroupBorderWidth(Item.Container, ASide, HasCaption)
else
Result := 0;
end;
function TdxLayoutGroupViewInfo.GetColor: TColor;
begin
Result := Options.GetColor;
end;
function TdxLayoutGroupViewInfo.GetIsDefaultColor: Boolean;
begin
Result := Options.Color = clDefault;
end;
function TdxLayoutGroupViewInfo.GetItemViewInfoClass(AItem: TdxCustomLayoutItem): TdxCustomLayoutItemViewInfoClass;
begin
Result := AItem.GetViewInfoClass;
end;
function TdxLayoutGroupViewInfo.GetMinVisibleHeight: Integer;
begin
Result := dxLayoutItemMinSize;
end;
function TdxLayoutGroupViewInfo.GetMinVisibleWidth: Integer;
begin
if HasCaption then
Result := CaptionViewInfo.CalculateMinWidth
else
Result := 0;
Result := Max(Result, dxLayoutItemMinSize);
end;
function TdxLayoutGroupViewInfo.GetOptions: TdxCustomLayoutLookAndFeelOptions;
begin
Result := LayoutLookAndFeel.GroupOptions;
end;
function TdxLayoutGroupViewInfo.GetRestSpaceBounds: TRect;
begin
Result := Bounds;
end;
function TdxLayoutGroupViewInfo.AllowChildHasBorder: Boolean;
begin
Result := Specific.AllowChildHasBorder;
end;
function TdxLayoutGroupViewInfo.GetSpecificClass: TdxLayoutGroupViewInfoSpecificClass;
begin
Result := Group.GetHelperClass.GetSpecificClass;
end;
procedure TdxLayoutGroupViewInfo.PaintSelectionLayer;
var
I: Integer;
begin
inherited;
for I := 0 to ItemViewInfoCount - 1 do
ItemViewInfos[I].PaintSelectionLayer;
end;
function TdxLayoutGroupViewInfo.GetHeight(AItemsAreaHeight: Integer): Integer;
begin
Result := Max(MinVisibleHeight,
BorderWidths[sdTop] + ItemsAreaOffsetVert + Specific.GetItemsAreaOffset(sdTop) +
AItemsAreaHeight +
BorderWidths[sdBottom] + ItemsAreaOffsetVert + Specific.GetItemsAreaOffset(sdBottom));
end;
function TdxLayoutGroupViewInfo.GetWidth(AItemsAreaWidth: Integer): Integer;
begin
Result := Max(MinVisibleWidth,
BorderWidths[sdLeft] + ItemsAreaOffsetHorz + Specific.GetItemsAreaOffset(sdLeft) +
AItemsAreaWidth +
BorderWidths[sdRight] + ItemsAreaOffsetHorz + Specific.GetItemsAreaOffset(sdRight));
end;
function TdxLayoutGroupViewInfo.HasBoundsFrame: Boolean;
begin
Result := Group.IsRoot and (Group.Container.ShowHiddenGroupsBounds or Group.Container.IsDesigning);
end;
function TdxLayoutGroupViewInfo.UseItemOffset: Boolean;
begin
Result := Group.UseIndent;
end;
function TdxLayoutGroupViewInfo.UseItemsAreaOffsets: Boolean;
begin
// #DG !!! Result := Group.ShowBorder or Group.IsRoot;
Result := HasBorder or Group.IsRoot;
end;
procedure TdxLayoutGroupViewInfo.Calculate(const ABounds: TRect);
begin
inherited;
CalculateClientBounds;
CalculateItemsAreaBounds;
CalculateCaptionViewInfoBounds;
CaptionViewInfo.Calculate(FCaptionAreaBounds);
Specific.Calculate(ItemsAreaBounds);
end;
procedure TdxLayoutGroupViewInfo.CalculateTabOrders(var AAvailTabOrder: Integer);
var
I: Integer;
begin
Specific.CalculateTabOrders(AAvailTabOrder);
for I := 0 to ItemViewInfoCount - 1 do
ItemViewInfos[I].CalculateTabOrders(AAvailTabOrder);
end;
function TdxLayoutGroupViewInfo.GetHitTest(const P: TPoint): TdxCustomLayoutHitTest;
var
I: Integer;
begin
Result := nil;
for I := 0 to ItemViewInfoCount - 1 do
begin
Result := ItemViewInfos[I].GetHitTest(P);
if Result <> nil then
Break;
end;
if Result = nil then
Result := Specific.GetHitTest(P);
if Result = nil then
Result := inherited GetHitTest(P);
end;
function TdxLayoutGroupViewInfo.GetItemWithMouse(const P: TPoint): TdxCustomLayoutItem;
var
I: Integer;
begin
Result := nil;
for I := 0 to ItemViewInfoCount - 1 do
begin
Result := ItemViewInfos[I].GetItemWithMouse(P);
if Result <> nil then
Break;
end;
if Result = nil then
Result := inherited GetItemWithMouse(P);
end;
function TdxLayoutGroupViewInfo.GetInsertionPos(const P: TPoint): Integer;
var
R: TRect;
begin
if PtInRect(Bounds, P) then
for Result := 0 to ItemViewInfoCount - 1 do
begin
R := ItemViewInfos[Result].Bounds;
if Specific.IsAtInsertionPos(R, P) then Exit;
end;
Result := ItemViewInfoCount;
end;
{ TdxCustomLayoutControlAdapter }
constructor TdxCustomLayoutControlAdapter.Create(AItem: TdxLayoutItem);
begin
inherited Create;
FItem := AItem;
if not FItem.IsLoading then
begin
Init;
if FItem.ActuallyVisible then
LayoutLookAndFeelChanged;
end;
end;
function TdxCustomLayoutControlAdapter.GetControl: TControl;
begin
Result := FItem.Control;
end;
function TdxCustomLayoutControlAdapter.GetLayoutLookAndFeel: TdxCustomLayoutLookAndFeel;
begin
Result := FItem.GetLayoutLookAndFeel;
end;
function TdxCustomLayoutControlAdapter.AllowCheckSize: Boolean;
begin
Result := True;
end;
procedure TdxCustomLayoutControlAdapter.HideControlBorder;
begin
SetEnumProp(Control, 'BorderStyle', 'bsNone');
end;
procedure TdxCustomLayoutControlAdapter.Init;
var
AHeight: Integer;
begin
FItem.ControlOptions.AutoColor := UseItemColor;
if FItem.IsDesigning and (FItem.Caption = '') then
FItem.Caption := Control.Name;//GetPlainString(TControlAccess(Control).Caption);
FItem.SetControlEnablement;
if FItem.IsDesigning then
FItem.ShowCaption := ShowItemCaption;
FItem.ControlOptions.ShowBorder := ShowBorder;
if ShowBorder then
begin
AHeight := Control.ClientHeight;
HideControlBorder;
Control.Height := AHeight;
end;
end;
function TdxCustomLayoutControlAdapter.ShowBorder: Boolean;
begin
Result :=
IsPublishedProp(Control, 'BorderStyle') and
(GetPropInfo(Control, 'BorderStyle').PropType^ = TypeInfo(Forms.TBorderStyle));
end;
function TdxCustomLayoutControlAdapter.ShowItemCaption: Boolean;
begin
Result := not IsPublishedProp(Control, 'Caption');
end;
function TdxCustomLayoutControlAdapter.UseItemColor: Boolean;
begin
Result :=
TControlAccess(Control).ParentColor and IsPublishedProp(Control, 'Color');
end;
procedure TdxCustomLayoutControlAdapter.LayoutLookAndFeelChanged;
begin
if Item.ControlOptions.AutoColor and (Item.ViewInfo <> nil) then
TControlAccess(Control).Color := Item.ViewInfo.Color;
end;
class procedure TdxCustomLayoutControlAdapter.Register(AControlClass: TControlClass);
begin
dxLayoutControlAdapterDefs.Register(AControlClass, Self);
end;
class procedure TdxCustomLayoutControlAdapter.Unregister(AControlClass: TControlClass);
begin
dxLayoutControlAdapterDefs.Unregister(AControlClass, Self);
end;
procedure TdxStoringOptions.Assign(Source: TPersistent);
var
ASourceOptions: TdxStoringOptions;
begin
if Source is TdxStoringOptions then
begin
ASourceOptions := TdxStoringOptions(Source);
IniFileName := ASourceOptions.IniFileName;
RegistryPath := ASourceOptions.RegistryPath;
StoreToIniFile := ASourceOptions.StoreToIniFile;
StoreToRegistry := ASourceOptions.StoreToRegistry;
end
else
inherited;
end;
function TdxStoringOptions.CanStoreToIniFile: Boolean;
begin
Result := StoreToIniFile and (IniFileName <> '');
end;
function TdxStoringOptions.CanStoreToRegistry: Boolean;
begin
Result := StoreToRegistry and (RegistryPath <> '');
end;
function TdxStoringOptions.CanRestoreFromIniFile: Boolean;
begin
Result := CanStoreToIniFile and FileExists(IniFileName);
end;
function TdxStoringOptions.CanRestoreFromRegistry: Boolean;
var
ARegistry: TRegistry;
begin
Result := CanStoreToRegistry;
if Result then
begin
ARegistry := TRegistry.Create(KEY_ALL_ACCESS);
try
Result := ARegistry.OpenKey(RegistryPath, False);
ARegistry.CloseKey;
finally
ARegistry.Free;
end;
end;
end;
{ TdxLayoutControlDragAndDropObject }
destructor TdxLayoutControlDragAndDropObject.Destroy;
begin
SourceItem := nil;
inherited;
end;
function TdxLayoutControlDragAndDropObject.CanDrop: Boolean;
begin
Result := (DestinationItem <> nil) or (SourceControl.ViewInfo.GetHitTest(CurMousePos).HitTestCode in
[htTreeViewItems, htClientArea, htGroup, htItem]);
end;
function TdxLayoutControlDragAndDropObject.CanRemove: Boolean;
begin
Result := (SourceControl.ViewInfo.GetHitTest(CurMousePos).HitTestCode in [htAvailableItems, htNone]) and
SourceItem.CanRemove and (Source <> dsCustomizeFormAvailableItems);
end;
function TdxLayoutControlDragAndDropObject.GetSourceControl: TdxCustomLayoutControl;
begin
Result := TdxCustomLayoutControl(inherited Control);
end;
procedure TdxLayoutControlDragAndDropObject.ResetDragAndDrop;
begin
SourceItem := nil;
DestinationItem := nil;
DestinationGroup := nil;
SourceControl.CustomizeFormUpdate([cfutContent, cfutSelection]);
end;
procedure TdxLayoutControlDragAndDropObject.SetAreaPart(Value: TdxLayoutAreaPart);
begin
if FAreaPart <> Value then
begin
FAreaPart := Value;
Dirty := True;
end;
end;
procedure TdxLayoutControlDragAndDropObject.SetDestinationControl(Value: TdxCustomLayoutControl);
begin
if FDestinationControl <> Value then
begin
FDestinationControl := Value;
Dirty := True;
end;
end;
procedure TdxLayoutControlDragAndDropObject.SetDestinationGroup(Value: TdxLayoutGroup);
begin
if FDestinationGroup <> Value then
begin
if FDestinationGroup <> nil then
FreeAndNil(FDestinationImage);
FDestinationGroup := Value;
if FDestinationGroup <> nil then
CreateDestinationImage;
Dirty := True;
end;
end;
procedure TdxLayoutControlDragAndDropObject.SetDestinationItem(Value: TdxCustomLayoutItem);
begin
if FDestinationItem <> Value then
begin
FDestinationItem := Value;
Dirty := True;
end;
end;
procedure TdxLayoutControlDragAndDropObject.SetSourceItem(Value: TdxCustomLayoutItem);
begin
if FSourceItem <> Value then
FSourceItem := Value;
end;
procedure TdxLayoutControlDragAndDropObject.CreateDragImage;
begin
FDragImage := TcxDragImage.Create;
PaintDragImage;
end;
procedure TdxLayoutControlDragAndDropObject.CreateDestinationImage;
var
R: TRect;
begin
FDestinationImage := TcxDragDestinationImage.Create;
FDestinationImage.ParentControl := DestinationControl;
R := DestinationGroup.ViewInfo.SelectionArea;
OffsetRect(R, -R.Left, -R.Top);
FDestinationImage.SetBounds(R.Left, R.Top, R.Right, R.Bottom);
end;
procedure TdxLayoutControlDragAndDropObject.DirtyChanged;
begin
inherited DirtyChanged;
FNeedRepaintDestinationImage := True;
end;
function TdxLayoutControlDragAndDropObject.GetDragAndDropCursor(Accepted: Boolean): TCursor;
const
Cursors: array [Boolean, Boolean] of TCursor = (
(crcxNoDrop, crdxLayoutControlDrag),
(crcxRemove, crdxLayoutControlDrag));
begin
Result := Cursors[CanRemove, CanDrop];
end;
procedure TdxLayoutControlDragAndDropObject.PaintDestinationImage;
function GetAreaPartBounds: TRect;
const
Width = 2;
var
AGroup: TdxLayoutGroup;
begin
Result := DestinationItem.ViewInfo.SelectionBorderRect;
case AreaPart of
apLeft:
with Result do
Right := Left + Width;
apTop:
with Result do
Bottom := Top + Width;
apRight:
with Result do
Left := Right - Width;
apBottom:
with Result do
Top := Bottom - Width;
apCenter:
begin
AGroup := DestinationItem as TdxLayoutGroup;
Result := AGroup.ViewInfo.ClientBounds;
case AGroup.LayoutDirection of
ldHorizontal:
with Result do
Right := Left + Width;
ldVertical:
with Result do
Bottom := Top + Width;
end;
InflateRect(Result, Integer(cxRectWidth(Result) = 0), Integer(cxRectHeight(Result) = 0));
end;
else
Result := cxInvalidRect;
end;
end;
var
R: TRect;
begin
FDestinationImage.Canvas.SaveState;
try
R := FDestinationImage.ClientRect;
FDestinationImage.Canvas.FrameRect(R, dxLayoutDestinationBorderColor);
InflateRect(R, -1, -1);
FDestinationImage.Canvas.FillRect(R, dxLayoutDestinationColor);
R := GetAreaPartBounds;
with DestinationGroup.ViewInfo.SelectionArea do
OffsetRect(R, -Left, -Top);
FDestinationImage.Canvas.FrameRect(R, dxLayoutDestinationBorderColor);
finally
FDestinationImage.Canvas.RestoreState;
end;
FNeedRepaintDestinationImage := False;
end;
procedure TdxLayoutControlDragAndDropObject.PaintDragImage;
var
AViewInfo: TdxCustomLayoutItemViewInfo;
function GetItemDragBounds: TRect;
begin
Result := AViewInfo.SelectionBorderRect;
end;
procedure CalculateDragImageOffset;
begin
if not SourceItem.ActuallyVisible then
FDragImageOffset := cxNullPoint
else
begin
case Source of
dsControl:
FDragImageOffset := cxPointOffset(GetItemDragBounds.TopLeft,
SourceControl.ScreenToClient(FStartDragPoint), False);
dsCustomizeFormTreeViewItems:
FDragImageOffset := cxPointOffset(GetItemDragBounds.TopLeft, cxRectCenter(GetItemDragBounds), False);
else
FDragImageOffset := cxNullPoint;
end;
end;
end;
function GetViewInfoBounds(AHasBorderChanged: Boolean): TRect;
begin
if SourceItem.IsAvailable then
Result := Rect(-AViewInfo.CalculateMinWidth, -AViewInfo.CalculateMinHeight, 0, 0)
else
begin
Result := AViewInfo.Bounds;
if AHasBorderChanged then
Result := TdxLayoutGroupViewInfo(AViewInfo).GetItemAreaBounds(Result);
end;
end;
var
ANeedDestroyViewInfo: Boolean;
APrevHasBorder: Boolean;
APrevBounds: TRect;
begin
if SourceItem.IsAvailable then
begin
AViewInfo := SourceItem.GetViewInfoClass.Create(SourceControl.ViewInfo, nil, SourceItem);
ANeedDestroyViewInfo := True;
end
else
begin
AViewInfo := SourceItem.ViewInfo;
ANeedDestroyViewInfo := False;
APrevBounds := AViewInfo.Bounds;
end;
try
APrevHasBorder := SourceItem.ViewInfo.HasBorder;
SourceControl.ViewInfo.IsDragImagePainted := True;
try
AViewInfo.Calculate(GetViewInfoBounds(SourceItem.ViewInfo.HasBorder <> APrevHasBorder));
FDragImage.SetBounds(0, 0, cxRectWidth(GetItemDragBounds), cxRectHeight(GetItemDragBounds));
FDragImage.Canvas.WindowOrg := GetItemDragBounds.TopLeft;
try
with AViewInfo.GetPainterClass.Create(FDragImage.Canvas, AViewInfo) do
try
Paint;
DoDrawSelectionFrame;
PaintSpecificPart;
finally
Free;
end;
finally
FDragImage.Canvas.WindowOrg := cxNullPoint;
end;
CalculateDragImageOffset;
finally
SourceControl.ViewInfo.IsDragImagePainted := False;
end;
finally
if ANeedDestroyViewInfo then
AViewInfo.Destroy
else
AViewInfo.Calculate(APrevBounds);
end;
end;
procedure TdxLayoutControlDragAndDropObject.RefreshDestinationImage;
var
P: TPoint;
begin
if (DestinationItem = nil) or (AreaPart = apNone) then Exit;
PaintDestinationImage;
if FDestinationImage.Visible then
FDestinationImage.Invalidate
else
begin
P := DestinationControl.ClientToScreen(DestinationGroup.ViewInfo.SelectionArea.TopLeft);
FDestinationImage.MoveTo(P);
FDestinationImage.Show;
end;
end;
procedure TdxLayoutControlDragAndDropObject.ShowDragImage(const P: TPoint);
begin
if FDragImage <> nil then
begin
FDragImage.MoveTo(P);
FDragImage.Show;
end;
end;
procedure TdxLayoutControlDragAndDropObject.BeginDragAndDrop;
begin
inherited BeginDragAndDrop;
//#DG SourceItem.SelectComponent([]);
SourceControl.DragAndDropBegan;
CreateDragImage;
end;
procedure TdxLayoutControlDragAndDropObject.DragAndDrop(const P: TPoint; var Accepted: Boolean);
function FindDestLayoutControl(const P: TPoint): TdxCustomLayoutControl;
var
AControl: TWinControl;
AWnd: THandle;
begin
Result := nil;
AWnd := cxWindowFromPoint(P);
while (Result = nil) and (AWnd <> 0) do
begin
AControl := FindControl(AWnd);
if (AControl is TdxCustomLayoutControl) and (AControl.Owner = SourceControl.Owner) and
TdxCustomLayoutControl(AControl).AllowDrop then
Result := TdxLayoutControl(AControl);
AWnd := GetAncestor(AWnd, GA_PARENT);
end;
if Result = nil then
Result := SourceControl;
end;
procedure DetermineDestinationControl(const P: TPoint);
begin
DestinationControl := FindDestLayoutControl(P);
end;
procedure DetermineDestinationItem(const P: TPoint);
var
AHitTest: TdxCustomLayoutHitTest;
begin
// DetermineDestinationItems(ADestItems);
// UpdatedestinationPlaces(AScreenPoint, ADestItems, ADestinationItem);
if IsWindowVisible(DestinationControl.Handle) then
AHitTest := DestinationControl.ViewInfo.GetHitTest(P)
else
AHitTest := nil;
if AHitTest is TdxCustomLayoutItemHitTest then
DestinationItem := TdxCustomLayoutItemHitTest(AHitTest).Item
else
if (AHitTest <> nil) and (AHitTest.HitTestCode = htClientArea) then
DestinationItem := DestinationControl.Items
else
DestinationItem := nil;
if (DestinationItem = SourceItem) or ((DestinationItem is TdxLayoutGroup) and not SourceItem.CanMoveTo(DestinationItem)) then
DestinationItem := nil;
end;
procedure DetermineAreaPart(const P: TPoint);
begin
if DestinationItem <> nil then
AreaPart := DestinationItem.ViewInfo.GetAreaPart(P)
else
AreaPart := apNone;
end;
procedure DetermineDestinationGroup;
begin
if DestinationItem = nil then
DestinationGroup := nil
else
begin
if DestinationItem.IsRoot or (AreaPart in [apCenter]) then
DestinationGroup := TdxLayoutGroup(DestinationItem)
else
DestinationGroup := DestinationItem.Parent;
end;
end;
var
AScreenPoint, ADestPoint, ADragImagePoint: TPoint;
begin
AScreenPoint := Control.ClientToScreen(P);
DetermineDestinationControl(AScreenPoint);
ADestPoint := DestinationControl.ScreenToClient(AScreenPoint);
ADragImagePoint := cxPointOffset(AScreenPoint, FDragImageOffset);
ShowDragImage(ADragImagePoint);
DetermineDestinationItem(ADestPoint);
DetermineAreaPart(ADestPoint);
DetermineDestinationGroup;
Accepted := AreaPart <> apNone;
if FNeedRepaintDestinationImage then
RefreshDestinationImage;
inherited;
end;
procedure TdxLayoutControlDragAndDropObject.EndDragAndDrop(Accepted: Boolean);
type
TActionType = (atNone, atInsert, atCreateGroup, atContentInsert);
function GetDestPosition: Integer;
begin
case AreaPart of
apRight, apBottom:
if DestinationItem.IsRoot then
Result := DestinationGroup.VisibleCount + 1
else
Result := DestinationItem.VisibleIndex + 1;
apLeft, apTop:
if DestinationItem.IsRoot then
Result := 0
else
Result := DestinationItem.VisibleIndex;
else
Result := 0;
end;
if (SourceItem.Parent = DestinationItem.Parent) and (SourceItem.VisibleIndex < Result) then
Dec(Result);
end;
function GetLayoutDirection: TdxLayoutDirection;
begin
Result := DestinationGroup.LayoutDirection;
end;
function GetOrthogonalDirection: TdxLayoutDirection;
begin
Result := DestinationGroup.GetHelperClass.GetOrthogonalDirection;
end;
function IsHorizontalAreaPart: Boolean;
begin
Result := AreaPart in [apLeft, apRight];
end;
function GetActionType: TActionType;
begin
if AreaPart = apNone then
Result := atNone
else
if (AreaPart = apCenter) or
not DestinationItem.IsRoot and
((GetLayoutDirection = ldHorizontal) and IsHorizontalAreaPart or
(GetLayoutDirection = ldVertical) and not IsHorizontalAreaPart or
(GetLayoutDirection = ldTabbed)) then
Result := atInsert
else
Result := atCreateGroup;
end;
procedure DoInsert;
begin
SourceItem.MoveTo(DestinationGroup, GetDestPosition, True);
end;
procedure DoCreateGroup;
const
LayoutDirections: array[Boolean] of TdxLayoutDirection =
(ldVertical, ldHorizontal);
var
AGroup: TdxLayoutGroup;
begin
if DestinationItem.IsRoot then
begin
DestinationGroup.PutChildrenIntoHiddenGroup;
DestinationGroup.LayoutDirection := LayoutDirections[IsHorizontalAreaPart];
SourceItem.MoveTo(DestinationGroup, GetDestPosition, True);
end
else
begin
AGroup := DestinationItem.PutIntoHiddenGroup(GetOrthogonalDirection);
SourceItem.MoveTo(AGroup, GetDestPosition, True);
end;
end;
procedure DoContentInsert;
begin
DestinationGroup.PutChildrenIntoHiddenGroup;
DestinationGroup.LayoutDirection := GetOrthogonalDirection;
SourceItem.MoveTo(DestinationGroup, GetDestPosition, True);
end;
function CanProcessDrop: Boolean;
begin
Result := Accepted and (DestinationControl <> nil);
end;
var
ANeedUpdateCustomizeForm: Boolean;
begin
FreeAndNil(FDragImage);
Dirty := True;
if CanProcessDrop then
begin
ANeedUpdateCustomizeForm := False;
SourceControl.CustomizeFormBeginUpdate;
DestinationControl.CustomizeFormBeginUpdate;
try
SourceControl.BeginUpdate;
DestinationControl.BeginUpdate;
try
if CanDrop and (DestinationItem <> nil) then
begin
ANeedUpdateCustomizeForm := True;
case GetActionType of
atInsert:
DoInsert;
atCreateGroup:
DoCreateGroup;
atContentInsert:
DoContentInsert;
end;
end
else
if CanRemove then
begin
SourceItem.Parent := nil;
ANeedUpdateCustomizeForm := True;
end;
finally
SourceItem := nil;
DestinationItem := nil;
DestinationGroup := nil;
SourceControl.EndUpdate;
DestinationControl.EndUpdate;
end;
finally
SourceControl.CustomizeFormCancelUpdate;
DestinationControl.CustomizeFormCancelUpdate;
if ANeedUpdateCustomizeForm then
begin
SourceControl.CustomizeFormUpdate([cfutContent, cfutSelection]);
if (DestinationControl <> SourceControl) and DestinationControl.IsCustomization then
DestinationControl.CustomizeFormUpdate([cfutContent, cfutSelection]);
end;
end;
SourceControl.Update;
if DestinationControl <> SourceControl then
DestinationControl.Update;
SourceControl.Modified;
end
else
ResetDragAndDrop;
inherited;
end;
procedure TdxLayoutControlDragAndDropObject.Init(ASource: TdxLayoutDragSource;
ASourceItem: TdxCustomLayoutItem);
begin
SourceControl.Update;
Source := ASource;
SourceItem := ASourceItem;
FStartDragPoint := GetMouseCursorPos;
end;
initialization
Screen.Cursors[crdxLayoutControlDrag] := LoadCursor(HInstance, 'DXLAYOUTCONTROLDRAGCURSOR');
RegisterClasses([TdxLayoutItem, TdxLayoutGroup, TdxLayoutAlignmentConstraint]);
HitTests := THitTests.Create;
dxLayoutSelectionHelperClass := TdxLayoutRunTimeSelectionHelper;
finalization
FreeAndNil(HitTests);
FreeAndNil(FGlobalCanvas);
end.