git-svn-id: https://192.168.0.254/svn/Componentes.Terceros.DevExpressVCL@38 05c56307-c608-d34a-929d-697000501d7a
11532 lines
337 KiB
ObjectPascal
11532 lines
337 KiB
ObjectPascal
{********************************************************************}
|
|
{ }
|
|
{ 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.
|