git-svn-id: https://192.168.0.254/svn/Componentes.Terceros.DevExpressVCL@55 05c56307-c608-d34a-929d-697000501d7a
1106 lines
36 KiB
ObjectPascal
1106 lines
36 KiB
ObjectPascal
{********************************************************************}
|
|
{ }
|
|
{ Developer Express Visual Component Library }
|
|
{ ExpressLayoutControl common routines }
|
|
{ }
|
|
{ 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 dxLayoutDragAndDrop;
|
|
|
|
{$I cxVer.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, Controls, Windows, Graphics,
|
|
cxClasses, cxControls, cxGraphics, dxLayoutControl;
|
|
|
|
type
|
|
TdxLayoutDragSource = (dsControl, dsCustomizeFormAvailableItems, dsCustomizeFormTreeViewItems);
|
|
|
|
{ TdxLayoutDragAndDropObject }
|
|
|
|
TdxLayoutCustomDragAndDropObject = class(TcxDragAndDropObject)
|
|
private
|
|
FSourceItem: TdxCustomLayoutItem;
|
|
FStartDragPoint: TPoint;
|
|
function GetSourceControl: TdxCustomLayoutControl;
|
|
protected
|
|
procedure Modified;
|
|
property SourceControl: TdxCustomLayoutControl read GetSourceControl;
|
|
public
|
|
procedure Init(ASource: TdxLayoutDragSource; ASourceItem: TdxCustomLayoutItem; const P: TPoint); virtual;
|
|
property SourceItem: TdxCustomLayoutItem read FSourceItem write FSourceItem;
|
|
end;
|
|
|
|
TdxLayoutDragAndDropObject = class(TdxLayoutCustomDragAndDropObject)
|
|
private
|
|
FAreaPart: TdxLayoutAreaPart;
|
|
FDragImage: TcxDragImage;
|
|
FDragImageOffset: TPoint;
|
|
FDragImagePoint: TPoint;
|
|
FDestinationControl: TdxCustomLayoutControl;
|
|
FDestinationGroup: TdxLayoutGroup;
|
|
FDestinationImage: TcxDragImage;
|
|
FDestinationItem: TdxCustomLayoutItem;
|
|
FHitTest: TdxCustomLayoutHitTest;
|
|
FNeedRepaintDestinationImage: Boolean;
|
|
FSource: TdxLayoutDragSource;
|
|
FSourceItemBounds: TRect;
|
|
|
|
procedure ResetDragAndDropObjects;
|
|
procedure SetAreaPart(Value: TdxLayoutAreaPart);
|
|
procedure SetDestinationControl(Value: TdxCustomLayoutControl);
|
|
procedure SetDestinationGroup(Value: TdxLayoutGroup);
|
|
procedure SetDestinationItem(Value: TdxCustomLayoutItem);
|
|
protected
|
|
procedure CreateDragImage;
|
|
procedure CreateDestinationImage;
|
|
procedure DirtyChanged; override;
|
|
function GetDragAndDropCursor(Accepted: Boolean): TCursor; override;
|
|
|
|
procedure PaintDestinationImage;
|
|
procedure PaintDragImage;
|
|
procedure RefreshDestinationImage;
|
|
procedure ShowDragImage;
|
|
|
|
procedure UpdateStates;
|
|
|
|
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 SourceItemBounds: TRect read FSourceItemBounds;
|
|
public
|
|
constructor Create(AControl: TcxControl); override;
|
|
destructor Destroy; override;
|
|
|
|
function CanDrop: Boolean;
|
|
function CanRemove: Boolean;
|
|
|
|
procedure BeginDragAndDrop; override;
|
|
procedure DragAndDrop(const P: TPoint; var Accepted: Boolean); override;
|
|
procedure EndDragAndDrop(Accepted: Boolean); override;
|
|
procedure Init(ASource: TdxLayoutDragSource; ASourceItem: TdxCustomLayoutItem; const P: TPoint); override;
|
|
end;
|
|
|
|
{ TdxLayoutDragAndDropObject }
|
|
|
|
TdxLayoutCustomSizingDragAndDropObject = class(TdxLayoutCustomDragAndDropObject)
|
|
protected
|
|
procedure RestoreSize; virtual;
|
|
public
|
|
procedure BeginDragAndDrop; override;
|
|
procedure EndDragAndDrop(Accepted: Boolean); override;
|
|
end;
|
|
|
|
TdxLayoutSizingDragAndDropObject = class(TdxLayoutCustomSizingDragAndDropObject) // cxinplaceContainer.TcxSizingDragAndDropObject
|
|
private
|
|
FOriginalSize: TSize;
|
|
FOriginalBounds: TRect;
|
|
FMarkerIndex: Integer;
|
|
protected
|
|
procedure RestoreSize; override;
|
|
public
|
|
constructor Create(AControl: TcxControl); override;
|
|
destructor Destroy; override;
|
|
|
|
procedure DragAndDrop(const P: TPoint; var Accepted: Boolean); override;
|
|
procedure Init(ASource: TdxLayoutDragSource; ASourceItem: TdxCustomLayoutItem; const P: TPoint); override;
|
|
end;
|
|
|
|
TdxLayoutSizingStrategy = (lssLeft, lssRight, lssClient, lssNone);
|
|
TdxLayoutSplitterDragAndDropObject = class(TdxLayoutCustomSizingDragAndDropObject)
|
|
private
|
|
FParentItem: TdxLayoutGroup;
|
|
|
|
FLeftItem: TdxCustomLayoutItem;
|
|
FRightItem: TdxCustomLayoutItem;
|
|
FOriginalSizes: array of TPoint;
|
|
|
|
FSizingStrategy: TdxLayoutSizingStrategy;
|
|
|
|
FLeftItemSize: Integer;
|
|
FRightItemSize: Integer;
|
|
|
|
FPrevPoint: TPoint;
|
|
protected
|
|
procedure RestoreSize; override;
|
|
|
|
function GetWorkAlign(AViewInfo: TdxCustomLayoutItemViewInfo): TdxLayoutAlignHorz; virtual; abstract;
|
|
function GetItemSize(AViewInfo: TdxCustomLayoutItemViewInfo): Integer; virtual; abstract;
|
|
function GetSignificantValue(const P: TPoint): Integer; virtual; abstract;
|
|
procedure SetItemSize(AViewInfo: TdxCustomLayoutItemViewInfo; ASize: Integer); virtual; abstract;
|
|
public
|
|
procedure DragAndDrop(const P: TPoint; var Accepted: Boolean); override;
|
|
procedure Init(ASource: TdxLayoutDragSource; ASourceItem: TdxCustomLayoutItem; const P: TPoint); override;
|
|
end;
|
|
|
|
TdxLayoutHSplitterDragAndDropObject = class(TdxLayoutSplitterDragAndDropObject)
|
|
protected
|
|
function GetWorkAlign(AViewInfo: TdxCustomLayoutItemViewInfo): TdxLayoutAlignHorz; override;
|
|
function GetItemSize(AViewInfo: TdxCustomLayoutItemViewInfo): Integer; override;
|
|
function GetSignificantValue(const P: TPoint): Integer; override;
|
|
procedure SetItemSize(AViewInfo: TdxCustomLayoutItemViewInfo; ASize: Integer); override;
|
|
end;
|
|
|
|
TdxLayoutVSplitterDragAndDropObject = class(TdxLayoutSplitterDragAndDropObject)
|
|
protected
|
|
function GetWorkAlign(AViewInfo: TdxCustomLayoutItemViewInfo): TdxLayoutAlignHorz; override;
|
|
function GetItemSize(AViewInfo: TdxCustomLayoutItemViewInfo): Integer; override;
|
|
function GetSignificantValue(const P: TPoint): Integer; override;
|
|
procedure SetItemSize(AViewInfo: TdxCustomLayoutItemViewInfo; ASize: Integer); override;
|
|
end;
|
|
|
|
{ TdxLayoutDragAndDropHelper }
|
|
|
|
TdxLayoutDragAndDropHelper = class(TdxLayoutControlPersistent)
|
|
private
|
|
FDragItem: TdxCustomLayoutItem;
|
|
FMouseDownPos: TPoint;
|
|
procedure BeginDragAndDrop(ASource: TdxLayoutDragSource);
|
|
function CanBeginDragAndDrop(X, Y: Integer): Boolean;
|
|
function GetDragAndDropObject: TdxLayoutDragAndDropObject;
|
|
protected
|
|
property DragAndDropObject: TdxLayoutDragAndDropObject 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;
|
|
|
|
function dxLayoutDragAndDropObject: TdxLayoutDragAndDropObject;
|
|
function dxLayoutSizingDragAndDropObject: TdxLayoutSizingDragAndDropObject;
|
|
|
|
implementation
|
|
|
|
uses
|
|
Types, SysUtils, Forms, Math, cxLibraryConsts, cxGeometry;
|
|
|
|
const
|
|
dxLayoutSelectionBorderDefaultColor: TColor = $BD8753;
|
|
dxLayoutDestinationColor = $D0D0EE;
|
|
dxLayoutDestinationBorderColor = $000059;
|
|
|
|
dxCustomizeFormHitTestCodes = [htCustomizeForm, htAvailableItems, htTreeViewItems];
|
|
|
|
var
|
|
FLayoutDragAndDropObject: TdxLayoutDragAndDropObject;
|
|
FLayoutSizingDragAndDropObject: TdxLayoutSizingDragAndDropObject;
|
|
|
|
type
|
|
TdxCustomLayoutControlAccess = class(TdxCustomLayoutControl);
|
|
TdxCustomLayoutItemAccess = class(TdxCustomLayoutItem);
|
|
TdxLayoutGroupAccess = class(TdxLayoutGroup);
|
|
TdxCustomLayoutItemViewInfoAccess = class(TdxCustomLayoutItemViewInfo);
|
|
TdxLayoutGroupViewInfoAccess = class(TdxLayoutGroupViewInfo);
|
|
TdxLayoutControlViewInfoAccess = class(TdxLayoutControlViewInfo);
|
|
TdxCustomLayoutItemPainterAccess = class(TdxCustomLayoutItemPainter);
|
|
|
|
function dxLayoutDragAndDropObject: TdxLayoutDragAndDropObject;
|
|
begin
|
|
Result := FLayoutDragAndDropObject;
|
|
end;
|
|
|
|
function dxLayoutSizingDragAndDropObject: TdxLayoutSizingDragAndDropObject;
|
|
begin
|
|
Result := FLayoutSizingDragAndDropObject;
|
|
end;
|
|
|
|
{ TdxLayoutCustomDragAndDropObject }
|
|
|
|
procedure TdxLayoutCustomDragAndDropObject.Init(ASource: TdxLayoutDragSource; ASourceItem: TdxCustomLayoutItem; const P: TPoint);
|
|
begin
|
|
FSourceItem := ASourceItem;
|
|
FStartDragPoint := P;
|
|
end;
|
|
|
|
procedure TdxLayoutCustomDragAndDropObject.Modified;
|
|
begin
|
|
TdxCustomLayoutControlAccess(SourceControl).Modified;
|
|
end;
|
|
|
|
function TdxLayoutCustomDragAndDropObject.GetSourceControl: TdxCustomLayoutControl;
|
|
begin
|
|
Result := inherited Control as TdxCustomLayoutControl;
|
|
end;
|
|
|
|
{ TdxLayoutDragAndDropObject }
|
|
|
|
constructor TdxLayoutDragAndDropObject.Create(AControl: TcxControl);
|
|
begin
|
|
inherited;
|
|
FLayoutDragAndDropObject := Self;
|
|
end;
|
|
|
|
destructor TdxLayoutDragAndDropObject.Destroy;
|
|
begin
|
|
FLayoutDragAndDropObject := nil;
|
|
inherited;
|
|
end;
|
|
|
|
function TdxLayoutDragAndDropObject.CanDrop: Boolean;
|
|
begin
|
|
Result := (DestinationGroup <> nil) and SourceItem.CanMoveTo(DestinationGroup) and
|
|
not TdxLayoutGroupAccess(DestinationGroup).IsLocked;
|
|
|
|
// (DestinationItem <> nil) or (FHitTest.HitTestCode in
|
|
// [htClientArea, htGroup, htItem]);
|
|
end;
|
|
|
|
function TdxLayoutDragAndDropObject.CanRemove: Boolean;
|
|
begin
|
|
Result := (FHitTest.HitTestCode in [htAvailableItems, htNone]) and
|
|
TdxCustomLayoutItemAccess(SourceItem).CanRemove and (SourceItem.Parent <> nil);
|
|
end;
|
|
|
|
procedure TdxLayoutDragAndDropObject.ResetDragAndDropObjects;
|
|
begin
|
|
SourceItem := nil;
|
|
DestinationItem := nil;
|
|
DestinationGroup := nil;
|
|
FHitTest := nil;
|
|
TdxCustomLayoutControlAccess(SourceControl).CustomizeFormPostUpdate([cfutDragAndDropState]);
|
|
end;
|
|
|
|
procedure TdxLayoutDragAndDropObject.SetAreaPart(Value: TdxLayoutAreaPart);
|
|
begin
|
|
if FAreaPart <> Value then
|
|
begin
|
|
FAreaPart := Value;
|
|
Dirty := True;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxLayoutDragAndDropObject.SetDestinationControl(Value: TdxCustomLayoutControl);
|
|
begin
|
|
if FDestinationControl <> Value then
|
|
begin
|
|
FDestinationControl := Value;
|
|
Dirty := True;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxLayoutDragAndDropObject.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 TdxLayoutDragAndDropObject.SetDestinationItem(Value: TdxCustomLayoutItem);
|
|
begin
|
|
if FDestinationItem <> Value then
|
|
begin
|
|
if FDestinationItem <> nil then
|
|
begin
|
|
if FHitTest.HitTestCode in dxCustomizeFormHitTestCodes then
|
|
DestinationItem.Container.CustomizeForm.ToggleHotTrackState(DestinationItem);
|
|
end;
|
|
FDestinationItem := Value;
|
|
if FDestinationItem <> nil then
|
|
begin
|
|
if FHitTest.HitTestCode in dxCustomizeFormHitTestCodes then
|
|
DestinationItem.Container.CustomizeForm.ToggleHotTrackState(DestinationItem);
|
|
end;
|
|
Dirty := True;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TdxLayoutDragAndDropObject.CreateDragImage;
|
|
begin
|
|
FDragImage := TcxDragImage.Create;
|
|
PaintDragImage;
|
|
end;
|
|
|
|
procedure TdxLayoutDragAndDropObject.CreateDestinationImage;
|
|
var
|
|
R: TRect;
|
|
begin
|
|
if (DestinationItem = nil) or TdxCustomLayoutItemAccess(DestinationItem).IsAvailable then
|
|
Exit;
|
|
FDestinationImage := TcxDragImage.Create;
|
|
FDestinationImage.PopupParent := GetParentForm(DestinationControl);
|
|
R := DestinationGroup.ViewInfo.SelectionArea;
|
|
cxRectIntersect(R, R, DestinationControl.ClientRect);
|
|
OffsetRect(R, -R.Left, -R.Top);
|
|
FDestinationImage.SetBounds(R.Left, R.Top, R.Right, R.Bottom);
|
|
end;
|
|
|
|
procedure TdxLayoutDragAndDropObject.DirtyChanged;
|
|
begin
|
|
inherited DirtyChanged;
|
|
FNeedRepaintDestinationImage := True;
|
|
end;
|
|
|
|
function TdxLayoutDragAndDropObject.GetDragAndDropCursor(Accepted: Boolean): TCursor;
|
|
begin
|
|
if CanDrop then
|
|
Result := crDefault
|
|
else
|
|
if CanRemove then
|
|
Result := crdxLayoutControlRemove
|
|
else
|
|
Result := crdxLayoutControlNoDrop;
|
|
end;
|
|
|
|
procedure TdxLayoutDragAndDropObject.PaintDestinationImage;
|
|
const
|
|
ABorderWidth = 1;
|
|
var
|
|
R: TRect;
|
|
ATargetRect: TRect;
|
|
AOffset: Integer;
|
|
begin
|
|
FDestinationImage.Canvas.SaveState;
|
|
try
|
|
R := FDestinationImage.ClientRect;
|
|
FDestinationImage.Canvas.FrameRect(R, dxLayoutDestinationBorderColor);
|
|
InflateRect(R, -ABorderWidth, -ABorderWidth);
|
|
FDestinationImage.Canvas.FillRect(R, dxLayoutDestinationColor);
|
|
|
|
ATargetRect := TdxLayoutGroupViewInfoAccess(DestinationGroup.ViewInfo).GetAreaPartBounds(AreaPart, DestinationItem.ViewInfo);
|
|
cxRectIntersect(R, DestinationGroup.ViewInfo.SelectionArea, DestinationControl.ClientRect);
|
|
with R do
|
|
ATargetRect := cxRectOffset(ATargetRect, -Left, -Top);
|
|
R := FDestinationImage.ClientRect;
|
|
AOffset := ABorderWidth + 1;
|
|
R := cxRectInflate(R, -AOffset, -AOffset);
|
|
if cxRectWidth(ATargetRect) < cxRectHeight(ATargetRect) then
|
|
begin
|
|
if ATargetRect.Left < R.Left then
|
|
ATargetRect := cxRectOffset(ATargetRect, R.Left - ATargetRect.Left, 0);
|
|
if ATargetRect.Right > R.Right then
|
|
ATargetRect := cxRectOffset(ATargetRect, R.Right - ATargetRect.Right, 0);
|
|
end
|
|
else
|
|
begin
|
|
if ATargetRect.Top < R.Top then
|
|
ATargetRect := cxRectOffset(ATargetRect, 0, R.Top - ATargetRect.Top);
|
|
if ATargetRect.Bottom > R.Bottom then
|
|
ATargetRect := cxRectOffset(ATargetRect, 0, R.Bottom - ATargetRect.Bottom);
|
|
end;
|
|
|
|
FDestinationImage.Canvas.FrameRect(ATargetRect, dxLayoutDestinationBorderColor);
|
|
finally
|
|
FDestinationImage.Canvas.RestoreState;
|
|
end;
|
|
FNeedRepaintDestinationImage := False;
|
|
end;
|
|
|
|
procedure TdxLayoutDragAndDropObject.PaintDragImage;
|
|
var
|
|
AViewInfo: TdxCustomLayoutItemViewInfo;
|
|
|
|
function GetItemDragBounds: TRect;
|
|
begin
|
|
Result := AViewInfo.SelectionBorderRect;
|
|
end;
|
|
|
|
procedure CalculateDragImageOffset;
|
|
begin
|
|
{#DG
|
|
if Source = dsControl then
|
|
FDragImageOffset := cxPointOffset(GetItemDragBounds.TopLeft,
|
|
SourceControl.ScreenToClient(FStartDragPoint), False)
|
|
else
|
|
}
|
|
FDragImageOffset := cxNullPoint;
|
|
end;
|
|
|
|
function GetViewInfoBounds(AHasBorderChanged: Boolean): TRect;
|
|
begin
|
|
if TdxCustomLayoutItemAccess(SourceItem).IsAvailable or not TdxCustomLayoutItemViewInfoAccess(AViewInfo).ActuallyVisible then
|
|
Result := Rect(-TdxCustomLayoutItemViewInfoAccess(AViewInfo).CalculateWidth, -TdxCustomLayoutItemViewInfoAccess(AViewInfo).CalculateHeight, 0, 0)
|
|
else
|
|
begin
|
|
Result := TdxCustomLayoutItemViewInfoAccess(AViewInfo).OriginalBounds;
|
|
if AHasBorderChanged then
|
|
Result := TdxLayoutGroupViewInfoAccess(AViewInfo).GetItemAreaBounds(Result);
|
|
end;
|
|
end;
|
|
|
|
var
|
|
ANeedDestroyViewInfo: Boolean;
|
|
APrevHasBorder: Boolean;
|
|
APrevBounds: TRect;
|
|
begin
|
|
if not TdxCustomLayoutItemAccess(SourceItem).ActuallyVisible then
|
|
begin
|
|
AViewInfo := TdxCustomLayoutItemAccess(SourceItem).GetViewInfoClass.Create(SourceControl.ViewInfo, nil, SourceItem);
|
|
ANeedDestroyViewInfo := True;
|
|
end
|
|
else
|
|
begin
|
|
AViewInfo := SourceItem.ViewInfo;
|
|
ANeedDestroyViewInfo := False;
|
|
APrevBounds := AViewInfo.Bounds;
|
|
end;
|
|
try
|
|
APrevHasBorder := TdxCustomLayoutItemViewInfoAccess(SourceItem.ViewInfo).HasBorder;
|
|
TdxLayoutControlViewInfoAccess(SourceControl.ViewInfo).IsDragImagePainted := True;
|
|
try
|
|
AViewInfo.Calculate(GetViewInfoBounds(TdxCustomLayoutItemViewInfoAccess(SourceItem.ViewInfo).HasBorder <> APrevHasBorder));
|
|
|
|
FDragImage.SetBounds(0, 0, cxRectWidth(GetItemDragBounds), cxRectHeight(GetItemDragBounds));
|
|
FDragImage.Canvas.WindowOrg := GetItemDragBounds.TopLeft;
|
|
try
|
|
with TdxCustomLayoutItemViewInfoAccess(AViewInfo).GetPainterClass.Create(FDragImage.Canvas, AViewInfo) do
|
|
try
|
|
PaintDragImage;
|
|
finally
|
|
Free;
|
|
end;
|
|
finally
|
|
FDragImage.Canvas.WindowOrg := cxNullPoint;
|
|
end;
|
|
CalculateDragImageOffset;
|
|
finally
|
|
TdxLayoutControlViewInfoAccess(SourceControl.ViewInfo).IsDragImagePainted := False;
|
|
end;
|
|
finally
|
|
if ANeedDestroyViewInfo then
|
|
AViewInfo.Destroy
|
|
else
|
|
AViewInfo.Calculate(APrevBounds);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxLayoutDragAndDropObject.RefreshDestinationImage;
|
|
var
|
|
P: TPoint;
|
|
begin
|
|
if (DestinationGroup = nil) or (DestinationItem = nil) or (AreaPart = apNone) or (FHitTest.HitTestCode in dxCustomizeFormHitTestCodes) then
|
|
Exit;
|
|
PaintDestinationImage;
|
|
if FDestinationImage.Visible then
|
|
FDestinationImage.Invalidate
|
|
else
|
|
begin
|
|
P := DestinationGroup.ViewInfo.SelectionArea.TopLeft;
|
|
P.X := Max(P.X, DestinationControl.ClientRect.Left);
|
|
P.Y := Max(P.Y, DestinationControl.ClientRect.Top);
|
|
P := DestinationControl.ClientToScreen(P);
|
|
|
|
FDestinationImage.MoveTo(P);
|
|
FDestinationImage.Show(SW_SHOWNOACTIVATE);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxLayoutDragAndDropObject.ShowDragImage;
|
|
begin
|
|
if FDragImage <> nil then
|
|
begin
|
|
FDragImage.MoveTo(FDragImagePoint);
|
|
FDragImage.Show;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxLayoutDragAndDropObject.UpdateStates;
|
|
|
|
function FindDestLayoutControl(const P: TPoint): TdxCustomLayoutControl;
|
|
var
|
|
AControl: TWinControl;
|
|
AWnd: THandle;
|
|
begin
|
|
Result := nil;
|
|
if SourceControl.IsDesigning then
|
|
begin
|
|
AWnd := cxWindowFromPoint(P);
|
|
while (Result = nil) and (AWnd <> 0) do
|
|
begin
|
|
AControl := FindControl(AWnd);
|
|
if (AControl is TdxCustomLayoutControl) and (AControl.Owner = SourceControl.Owner) and
|
|
TdxCustomLayoutControlAccess(AControl).AllowDrop then
|
|
Result := TdxLayoutControl(AControl);
|
|
AWnd := GetAncestor(AWnd, GA_PARENT);
|
|
end;
|
|
end;
|
|
if Result = nil then
|
|
Result := SourceControl;
|
|
end;
|
|
|
|
procedure DetermineDestinationControl(AHitControl: TdxCustomLayoutControl);
|
|
begin
|
|
if DestinationItem = nil then
|
|
DestinationControl := AHitControl
|
|
else
|
|
DestinationControl := DestinationItem.Container;
|
|
end;
|
|
|
|
procedure DetermineDestinationItem;
|
|
var
|
|
ADestinationItem: TdxCustomLayoutItem;
|
|
begin
|
|
// DetermineDestinationItems(ADestItems);
|
|
// UpdatedestinationPlaces(AScreenPoint, ADestItems, ADestinationItem);
|
|
|
|
ADestinationItem := FHitTest.GetDestinationItem;
|
|
if (ADestinationItem = SourceItem) or
|
|
((ADestinationItem is TdxLayoutGroup) and not SourceItem.CanMoveTo(ADestinationItem)) then
|
|
ADestinationItem := nil;
|
|
DestinationItem := ADestinationItem;
|
|
|
|
if (DestinationItem <> nil) and (DestinationItem.Container <> DestinationControl) then
|
|
DestinationControl := DestinationItem.Container;
|
|
end;
|
|
|
|
procedure DetermineAreaPart(const P: TPoint);
|
|
const
|
|
CustomizeFormTreeViewItemAreaPart: array [TdxLayoutDirection] of TdxLayoutAreaPart = (apRight, apBottom, apBottom);
|
|
var
|
|
AAreaPart: TdxLayoutAreaPart;
|
|
begin
|
|
AAreaPart := apNone;
|
|
if FHitTest.IsDeterminedAreaPart then
|
|
AAreaPart := FHitTest.GetAreaPart
|
|
else
|
|
if (DestinationItem <> nil) then
|
|
AAreaPart := TdxCustomLayoutItemViewInfoAccess(DestinationItem.ViewInfo).GetAreaPart(P);
|
|
AreaPart := AAreaPart;
|
|
end;
|
|
|
|
procedure DetermineDestinationGroup;
|
|
begin
|
|
if DestinationItem = nil then
|
|
DestinationGroup := nil
|
|
else
|
|
begin
|
|
if DestinationItem.IsRoot or (AreaPart in [apCenter, apFirstChild, apLastChild]) then
|
|
DestinationGroup := TdxLayoutGroup(DestinationItem)
|
|
else
|
|
DestinationGroup := DestinationItem.Parent;
|
|
end;
|
|
end;
|
|
|
|
procedure DetermineHitTest(AHitControl: TdxCustomLayoutControl; const P: TPoint);
|
|
begin
|
|
FHitTest := AHitControl.GetHitTest(AHitControl.ScreenToClient(P));
|
|
end;
|
|
|
|
var
|
|
AScreenPoint, ADestPoint: TPoint;
|
|
AHitControl: TdxCustomLayoutControl;
|
|
begin
|
|
AScreenPoint := GetMouseCursorPos;
|
|
AHitControl := FindDestLayoutControl(AScreenPoint);
|
|
FDragImagePoint := cxPointOffset(AScreenPoint, FDragImageOffset);
|
|
|
|
DetermineHitTest(AHitControl, AScreenPoint);
|
|
DetermineDestinationItem;
|
|
DetermineDestinationControl(AHitControl);
|
|
ADestPoint := DestinationControl.ScreenToClient(AScreenPoint);
|
|
DetermineAreaPart(ADestPoint);
|
|
DetermineDestinationGroup;
|
|
end;
|
|
|
|
procedure TdxLayoutDragAndDropObject.BeginDragAndDrop;
|
|
begin
|
|
inherited BeginDragAndDrop;
|
|
//#DG SourceItem.SelectComponent([]);
|
|
TdxCustomLayoutControlAccess(SourceControl).DragAndDropBegan;
|
|
CreateDragImage;
|
|
end;
|
|
|
|
procedure TdxLayoutDragAndDropObject.DragAndDrop(const P: TPoint; var Accepted: Boolean);
|
|
|
|
procedure UpdateDestinationImageState;
|
|
begin
|
|
if FNeedRepaintDestinationImage then
|
|
RefreshDestinationImage;
|
|
end;
|
|
|
|
begin
|
|
UpdateStates;
|
|
ShowDragImage;
|
|
Accepted := AreaPart <> apNone;
|
|
UpdateDestinationImageState;
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxLayoutDragAndDropObject.EndDragAndDrop(Accepted: Boolean);
|
|
|
|
function GetDestPosition: Integer;
|
|
begin
|
|
case AreaPart of
|
|
apRight, apBottom, apAfter:
|
|
if DestinationItem = DestinationGroup then
|
|
Result := DestinationGroup.Count
|
|
else
|
|
Result := DestinationItem.Index + 1;
|
|
apLeft, apTop, apBefore:
|
|
if DestinationItem = DestinationGroup then
|
|
Result := 0
|
|
else
|
|
Result := DestinationItem.Index;
|
|
apLastChild:
|
|
Result := DestinationGroup.Count;
|
|
else
|
|
Result := 0;
|
|
end;
|
|
if (SourceItem.Parent = DestinationGroup) and (SourceItem.Index < Result) then
|
|
Dec(Result);
|
|
end;
|
|
|
|
function GetLayoutDirection: TdxLayoutDirection;
|
|
begin
|
|
Result := DestinationGroup.LayoutDirection;
|
|
end;
|
|
|
|
function GetOrthogonalDirection: TdxLayoutDirection;
|
|
begin
|
|
Result := TdxLayoutGroupAccess(DestinationItem.Parent).GetHelperClass.GetOrthogonalDirection;
|
|
end;
|
|
|
|
function IsHorizontalAreaPart: Boolean;
|
|
begin
|
|
Result := AreaPart in [apLeft, apRight, apAfter, apBefore];
|
|
end;
|
|
|
|
function IsVerticalAreaPart: Boolean;
|
|
begin
|
|
Result := AreaPart in [apTop, apBottom, apAfter, apBefore];
|
|
end;
|
|
|
|
procedure DoInsert;
|
|
begin
|
|
SourceItem.Move(DestinationGroup, GetDestPosition, True);
|
|
end;
|
|
|
|
procedure DoCreateGroup;
|
|
const
|
|
LayoutDirections: array[Boolean] of TdxLayoutDirection =
|
|
(ldVertical, ldHorizontal);
|
|
var
|
|
AParentGroup: TdxLayoutGroup;
|
|
begin
|
|
if DestinationItem.IsRoot then
|
|
begin
|
|
DestinationGroup.PutChildrenIntoHiddenGroup;
|
|
DestinationGroup.LayoutDirection := LayoutDirections[IsHorizontalAreaPart];
|
|
AParentGroup := DestinationGroup;
|
|
end
|
|
else
|
|
AParentGroup := DestinationItem.PutIntoHiddenGroup(GetOrthogonalDirection);
|
|
TdxLayoutGroupAccess(AParentGroup).BuildVisibleItemsList;
|
|
SourceItem.Move(AParentGroup, GetDestPosition, True);
|
|
end;
|
|
|
|
procedure DoContentInsert;
|
|
begin
|
|
DestinationGroup.PutChildrenIntoHiddenGroup;
|
|
DestinationGroup.LayoutDirection := GetOrthogonalDirection;
|
|
SourceItem.Move(DestinationGroup, GetDestPosition, True);
|
|
end;
|
|
|
|
function CanProcessDrop: Boolean;
|
|
begin
|
|
Result := Accepted and (DestinationControl <> nil) and ((CanDrop and (DestinationItem <> nil)) or CanRemove);
|
|
end;
|
|
|
|
function GetActionType(AAreaPart: TdxLayoutAreaPart): TdxLayoutActionType;
|
|
begin
|
|
if AAreaPart in [apBefore, apAfter, apFirstChild, apLastChild] then
|
|
Result := atInsert
|
|
else
|
|
Result := TdxLayoutGroupViewInfoAccess(DestinationGroup.ViewInfo).GetActionType(AAreaPart);
|
|
end;
|
|
|
|
var
|
|
ALinkSelf: TcxObjectLink;
|
|
begin
|
|
FreeAndNil(FDragImage);
|
|
UpdateStates;
|
|
Dirty := True;
|
|
if CanProcessDrop then
|
|
begin
|
|
TdxCustomLayoutControlAccess(DestinationControl).SaveToUndo;
|
|
DestinationControl.BeginUpdate;
|
|
TdxCustomLayoutControlAccess(SourceControl).SaveToUndo;
|
|
SourceControl.BeginUpdate;
|
|
try
|
|
if CanDrop and (DestinationGroup <> nil) then
|
|
case GetActionType(AreaPart) of
|
|
atInsert:
|
|
DoInsert;
|
|
atCreateGroup:
|
|
DoCreateGroup;
|
|
atContentInsert:
|
|
DoContentInsert;
|
|
end
|
|
else
|
|
if CanRemove then
|
|
SourceItem.Parent := nil;
|
|
finally
|
|
ALinkSelf := cxAddObjectLink(SourceItem);
|
|
try
|
|
ResetDragAndDropObjects;
|
|
SourceControl.EndUpdate;
|
|
DestinationControl.EndUpdate;
|
|
if ALinkSelf.Ref <> nil then
|
|
(ALinkSelf.Ref as TdxCustomLayoutItem).MakeVisible;
|
|
finally
|
|
cxRemoveObjectLink(ALinkSelf);
|
|
end;
|
|
end;
|
|
SourceControl.Update;
|
|
if DestinationControl <> SourceControl then
|
|
DestinationControl.Update;
|
|
Modified;
|
|
end
|
|
else
|
|
ResetDragAndDropObjects;
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxLayoutDragAndDropObject.Init(ASource: TdxLayoutDragSource; ASourceItem: TdxCustomLayoutItem; const P: TPoint);
|
|
begin
|
|
inherited;
|
|
SourceControl.Update;
|
|
Source := ASource;
|
|
end;
|
|
|
|
{ TdxLayoutCustomSizingDragAndDropObject }
|
|
|
|
procedure TdxLayoutCustomSizingDragAndDropObject.BeginDragAndDrop;
|
|
begin
|
|
inherited;
|
|
TdxCustomLayoutControlAccess(Control).SaveToUndo;
|
|
end;
|
|
|
|
procedure TdxLayoutCustomSizingDragAndDropObject.EndDragAndDrop(Accepted: Boolean);
|
|
begin
|
|
if not Accepted then
|
|
RestoreSize
|
|
else
|
|
Modified;
|
|
end;
|
|
|
|
procedure TdxLayoutCustomSizingDragAndDropObject.RestoreSize;
|
|
begin
|
|
// do nothing
|
|
end;
|
|
|
|
{ TdxLayoutSizingDragAndDropObject }
|
|
|
|
constructor TdxLayoutSizingDragAndDropObject.Create(AControl: TcxControl);
|
|
begin
|
|
inherited;
|
|
FLayoutSizingDragAndDropObject := Self;
|
|
end;
|
|
|
|
destructor TdxLayoutSizingDragAndDropObject.Destroy;
|
|
begin
|
|
FLayoutSizingDragAndDropObject := nil;
|
|
inherited;
|
|
end;
|
|
|
|
procedure TdxLayoutSizingDragAndDropObject.DragAndDrop(const P: TPoint; var Accepted: Boolean);
|
|
var
|
|
XC, YC: Integer;
|
|
begin
|
|
if SourceItem.AlignHorz in [ahCenter] then
|
|
XC := 2
|
|
else
|
|
XC := 1;
|
|
|
|
if SourceItem.AlignVert in [avCenter] then
|
|
YC := 2
|
|
else
|
|
YC := 1;
|
|
|
|
if FMarkerIndex in [0, 6, 7] then
|
|
SourceItem.Width := cxRectWidth(FOriginalBounds) + XC * (FStartDragPoint.X - P.X);
|
|
if FMarkerIndex in [2, 3, 4] then
|
|
SourceItem.Width := cxRectWidth(FOriginalBounds) + XC * (P.X - FStartDragPoint.X);
|
|
if FMarkerIndex in [0, 1, 2] then
|
|
SourceItem.Height := cxRectHeight(FOriginalBounds) + YC * (FStartDragPoint.Y - P.Y);
|
|
if FMarkerIndex in [4, 5, 6] then
|
|
SourceItem.Height := cxRectHeight(FOriginalBounds) + YC * (P.Y - FStartDragPoint.Y);
|
|
end;
|
|
|
|
procedure TdxLayoutSizingDragAndDropObject.Init(ASource: TdxLayoutDragSource; ASourceItem: TdxCustomLayoutItem; const P: TPoint);
|
|
begin
|
|
inherited;
|
|
FOriginalSize := cxSize(ASourceItem.Width, ASourceItem.Height);
|
|
FOriginalBounds := ASourceItem.ViewInfo.Bounds;
|
|
FMarkerIndex := TdxCustomLayoutItemViewInfoAccess(ASourceItem.ViewInfo).GetMarkerIndex(P);
|
|
end;
|
|
|
|
procedure TdxLayoutSizingDragAndDropObject.RestoreSize;
|
|
begin
|
|
SourceItem.Width := FOriginalSize.cx;
|
|
SourceItem.Height := FOriginalSize.cy;
|
|
end;
|
|
|
|
{ TdxLayoutSplitterDragAndDropObject }
|
|
|
|
procedure TdxLayoutSplitterDragAndDropObject.DragAndDrop(const P: TPoint; var Accepted: Boolean);
|
|
begin
|
|
if not cxPointIsEqual(FPrevPoint, P) then
|
|
begin
|
|
FPrevPoint := P;
|
|
case FSizingStrategy of
|
|
lssLeft: SetItemSize(FLeftItem.ViewInfo, FLeftItemSize + (GetSignificantValue(P) - GetSignificantValue(FStartDragPoint)));
|
|
lssRight: SetItemSize(FRightItem.ViewInfo, FRightItemSize + (GetSignificantValue(FStartDragPoint) - GetSignificantValue(P)));
|
|
lssClient:
|
|
begin
|
|
SourceControl.BeginUpdate;
|
|
try
|
|
SetItemSize(FLeftItem.ViewInfo, FLeftItemSize + (GetSignificantValue(P) - GetSignificantValue(FStartDragPoint)));
|
|
SetItemSize(FRightItem.ViewInfo, FRightItemSize + (GetSignificantValue(FStartDragPoint) - GetSignificantValue(P)));
|
|
finally
|
|
SourceControl.EndUpdate(False);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxLayoutSplitterDragAndDropObject.Init(ASource: TdxLayoutDragSource; ASourceItem: TdxCustomLayoutItem; const P: TPoint);
|
|
|
|
function GetLeftItem: TdxCustomLayoutItem;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result := nil;
|
|
for I := ASourceItem.VisibleIndex - 1 downto 0 do
|
|
if GetWorkAlign(FParentItem.VisibleItems[I].ViewInfo) in [GetWorkAlign(FSourceItem.ViewInfo), ahClient] then
|
|
begin
|
|
Result := FParentItem.VisibleItems[I];
|
|
Break;
|
|
end;
|
|
end;
|
|
|
|
function GetRightItem: TdxCustomLayoutItem;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result := nil;
|
|
for I := ASourceItem.VisibleIndex + 1 to FParentItem.VisibleCount - 1 do
|
|
if GetWorkAlign(FParentItem.VisibleItems[I].ViewInfo) in [GetWorkAlign(FSourceItem.ViewInfo), ahClient] then
|
|
begin
|
|
Result := FParentItem.VisibleItems[I];
|
|
Break;
|
|
end;
|
|
end;
|
|
|
|
function GetSimpleStrategy(AAlign: TdxLayoutAlignHorz): TdxLayoutSizingStrategy;
|
|
begin
|
|
case AAlign of
|
|
ahLeft:
|
|
if (FLeftItem <> nil) and not TdxCustomLayoutItemAccess(FLeftItem).IsLocked then
|
|
Result := lssLeft
|
|
else
|
|
Result := lssNone;
|
|
ahRight:
|
|
if (FRightItem <> nil) and not TdxCustomLayoutItemAccess(FRightItem).IsLocked then
|
|
Result := lssRight
|
|
else
|
|
Result := lssNone;
|
|
else
|
|
Result := lssNone;
|
|
end;
|
|
if (Result in [lssRight, lssLeft]) and (FLeftItem <> nil) and (FRightItem <> nil) and
|
|
(GetWorkAlign(FLeftItem.ViewInfo) = ahClient) and (GetWorkAlign(FRightItem.ViewInfo) = ahClient) then
|
|
Result := lssClient;
|
|
end;
|
|
|
|
var
|
|
I: Integer;
|
|
begin
|
|
inherited;
|
|
|
|
FParentItem := ASourceItem.Parent;
|
|
|
|
SetLength(FOriginalSizes, FParentItem.VisibleCount);
|
|
for I := 0 to FParentItem.VisibleCount - 1 do
|
|
FOriginalSizes[I] := Point(FParentItem.VisibleItems[I].Width, FParentItem.VisibleItems[I].Height);
|
|
|
|
FLeftItem := GetLeftItem;
|
|
FRightItem := GetRightItem;
|
|
if FLeftItem <> nil then
|
|
FLeftItemSize := GetItemSize(FLeftItem.ViewInfo);
|
|
if FRightItem <> nil then
|
|
FRightItemSize := GetItemSize(FRightItem.ViewInfo);
|
|
|
|
case GetWorkAlign(FSourceItem.ViewInfo) of
|
|
ahLeft:
|
|
if (FLeftItem <> nil) and (GetWorkAlign(FLeftItem.ViewInfo) = ahClient) then
|
|
FSizingStrategy := GetSimpleStrategy(ahRight)
|
|
else
|
|
FSizingStrategy := GetSimpleStrategy(ahLeft);
|
|
ahRight:
|
|
if (FRightItem <> nil) and (GetWorkAlign(FRightItem.ViewInfo) = ahClient) then
|
|
FSizingStrategy := GetSimpleStrategy(ahLeft)
|
|
else
|
|
FSizingStrategy := GetSimpleStrategy(ahRight);
|
|
else
|
|
FSizingStrategy := lssNone;
|
|
end;
|
|
|
|
if FSizingStrategy = lssClient then
|
|
begin
|
|
SourceControl.BeginUpdate;
|
|
try
|
|
for I := 0 to FParentItem.VisibleCount - 1 do
|
|
if GetWorkAlign(FParentItem.VisibleItems[I].ViewInfo) = ahClient then
|
|
SetItemSize(FParentItem.VisibleItems[I].ViewInfo, GetItemSize(FParentItem.VisibleItems[I].ViewInfo));
|
|
finally
|
|
SourceControl.CancelUpdate;
|
|
end;
|
|
end;
|
|
|
|
FPrevPoint := P;
|
|
end;
|
|
|
|
procedure TdxLayoutSplitterDragAndDropObject.RestoreSize;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
SourceControl.BeginUpdate;
|
|
try
|
|
for I := 0 to FParentItem.VisibleCount - 1 do
|
|
SetItemSize(FParentItem.VisibleItems[I].ViewInfo, GetSignificantValue(FOriginalSizes[I]));
|
|
finally
|
|
SourceControl.EndUpdate(False);
|
|
end;
|
|
end;
|
|
|
|
{ TdxLayoutHSplitterDragAndDropObject }
|
|
|
|
function TdxLayoutHSplitterDragAndDropObject.GetWorkAlign(AViewInfo: TdxCustomLayoutItemViewInfo): TdxLayoutAlignHorz;
|
|
begin
|
|
Result := AViewInfo.AlignHorz;
|
|
end;
|
|
|
|
function TdxLayoutHSplitterDragAndDropObject.GetItemSize(AViewInfo: TdxCustomLayoutItemViewInfo): Integer;
|
|
begin
|
|
Result := cxRectWidth(AViewInfo.Bounds);
|
|
end;
|
|
|
|
function TdxLayoutHSplitterDragAndDropObject.GetSignificantValue(const P: TPoint): Integer;
|
|
begin
|
|
Result := P.X;
|
|
end;
|
|
|
|
procedure TdxLayoutHSplitterDragAndDropObject.SetItemSize(AViewInfo: TdxCustomLayoutItemViewInfo; ASize: Integer);
|
|
begin
|
|
TdxCustomLayoutItemViewInfoAccess(AViewInfo).Item.Width := ASize;
|
|
end;
|
|
|
|
{ TdxLayoutHSplitterDragAndDropObject }
|
|
|
|
function TdxLayoutVSplitterDragAndDropObject.GetWorkAlign(AViewInfo: TdxCustomLayoutItemViewInfo): TdxLayoutAlignHorz;
|
|
begin
|
|
Result := TdxLayoutAlignHorz(AViewInfo.AlignVert);
|
|
end;
|
|
|
|
function TdxLayoutVSplitterDragAndDropObject.GetItemSize(AViewInfo: TdxCustomLayoutItemViewInfo): Integer;
|
|
begin
|
|
Result := cxRectHeight(AViewInfo.Bounds);
|
|
end;
|
|
|
|
function TdxLayoutVSplitterDragAndDropObject.GetSignificantValue(const P: TPoint): Integer;
|
|
begin
|
|
Result := P.Y;
|
|
end;
|
|
|
|
procedure TdxLayoutVSplitterDragAndDropObject.SetItemSize(AViewInfo: TdxCustomLayoutItemViewInfo; ASize: Integer);
|
|
begin
|
|
TdxCustomLayoutItemViewInfoAccess(AViewInfo).Item.Height := ASize;
|
|
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 := TdxCustomLayoutControlAccess(Control).CanDragAndDrop and (Control.DragAndDropState = ddsNone) and
|
|
not cxPointIsEqual(FMouseDownPos, cxInvalidPoint) and not IsPointInDragDetectArea(FMouseDownPos, X, Y) and
|
|
(DragItem <> nil) and TdxCustomLayoutItemAccess(DragItem).CanDragAndDrop;
|
|
end;
|
|
|
|
procedure TdxLayoutDragAndDropHelper.BeginDragAndDrop(ASource: TdxLayoutDragSource);
|
|
begin
|
|
DragAndDropObject.Init(ASource, DragItem, GetMouseCursorPos);
|
|
Control.BeginDragAndDrop;
|
|
end;
|
|
|
|
function TdxLayoutDragAndDropHelper.GetDragAndDropObject: TdxLayoutDragAndDropObject;
|
|
begin
|
|
Result := TdxLayoutDragAndDropObject(Control.DragAndDropObject);
|
|
end;
|
|
|
|
initialization
|
|
Screen.Cursors[crdxLayoutControlNoDrop] := LoadCursor(HInstance, 'DXLAYOUTCONTROLNODROP');
|
|
Screen.Cursors[crdxLayoutControlRemove] := LoadCursor(HInstance, 'DXLAYOUTCONTROLREMOVE');
|
|
|
|
end.
|