mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-09-01 21:40:25 +02:00
ideintf: implement drag-drop for collection items in the component treeview
git-svn-id: trunk@23181 -
This commit is contained in:
parent
f5ace1ab3f
commit
222c9222e3
@ -273,10 +273,12 @@ end;
|
|||||||
procedure TComponentTreeView.DragDrop(Source: TObject; X, Y: Integer);
|
procedure TComponentTreeView.DragDrop(Source: TObject; X, Y: Integer);
|
||||||
var
|
var
|
||||||
Node, SelNode: TTreeNode;
|
Node, SelNode: TTreeNode;
|
||||||
|
ACollection: TCollection;
|
||||||
AContainer: TWinControl;
|
AContainer: TWinControl;
|
||||||
AControl: TControl;
|
AControl: TControl;
|
||||||
ParentNode: TTreeNode;
|
ParentNode: TTreeNode;
|
||||||
InsertType: TTreeViewInsertMarkType;
|
InsertType: TTreeViewInsertMarkType;
|
||||||
|
NewIndex, AIndex: Integer;
|
||||||
ok: Boolean;
|
ok: Boolean;
|
||||||
begin
|
begin
|
||||||
GetComponentInsertMarkAt(X, Y, Node, InsertType);
|
GetComponentInsertMarkAt(X, Y, Node, InsertType);
|
||||||
@ -300,17 +302,51 @@ begin
|
|||||||
AControl.Parent := AContainer;
|
AControl.Parent := AContainer;
|
||||||
ok:=true;
|
ok:=true;
|
||||||
except
|
except
|
||||||
on E: Exception do begin
|
on E: Exception do
|
||||||
MessageDlg(oisError,
|
MessageDlg(oisError,
|
||||||
Format(oisUnableToChangeParentOfControlToNewParent, ['"',
|
Format(oisUnableToChangeParentOfControlToNewParent, ['"',
|
||||||
DbgSName(AControl), '"', '"', DbgSName(AContainer), '"', #13,
|
DbgSName(AControl), '"', '"', DbgSName(AContainer), '"', #13,
|
||||||
E.Message]), mtError, [mbCancel], 0);
|
E.Message]), mtError, [mbOk], 0);
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
if not ok then break;
|
if not ok then break;
|
||||||
end;
|
end;
|
||||||
SelNode := SelNode.GetNextMultiSelected;
|
SelNode := SelNode.GetNextMultiSelected;
|
||||||
end;
|
end;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if TObject(Node.Data) is TCollectionItem then
|
||||||
|
begin
|
||||||
|
ACollection := TCollectionItem(Node.Data).Collection;
|
||||||
|
ACollection.BeginUpdate;
|
||||||
|
case InsertType of
|
||||||
|
tvimAsNextSibling:
|
||||||
|
NewIndex := TCollectionItem(Node.Data).Index + 1;
|
||||||
|
tvimAsPrevSibling:
|
||||||
|
NewIndex := TCollectionItem(Node.Data).Index;
|
||||||
|
end;
|
||||||
|
SelNode := GetLastMultiSelected;
|
||||||
|
while Assigned(SelNode) do
|
||||||
|
begin
|
||||||
|
if (TObject(SelNode.Data) is TCollectionItem) and
|
||||||
|
(TCollectionItem(SelNode.Data).Collection = ACollection) then
|
||||||
|
begin
|
||||||
|
ok := False;
|
||||||
|
try
|
||||||
|
AIndex := TCollectionItem(SelNode.Data).Index;
|
||||||
|
if AIndex < NewIndex then
|
||||||
|
TCollectionItem(SelNode.Data).Index := NewIndex - 1
|
||||||
|
else
|
||||||
|
TCollectionItem(SelNode.Data).Index := NewIndex;
|
||||||
|
ok := True;
|
||||||
|
except
|
||||||
|
on E: Exception do
|
||||||
|
MessageDlg(E.Message, mtError, [mbOk], 0);
|
||||||
|
end;
|
||||||
|
if not ok then break;
|
||||||
|
end;
|
||||||
|
SelNode := SelNode.GetPrevMultiSelected;
|
||||||
|
end;
|
||||||
|
ACollection.EndUpdate;
|
||||||
end;
|
end;
|
||||||
RebuildComponentNodes;
|
RebuildComponentNodes;
|
||||||
end;
|
end;
|
||||||
@ -323,7 +359,7 @@ var
|
|||||||
Node: TTreeNode;
|
Node: TTreeNode;
|
||||||
AnObject: TObject;
|
AnObject: TObject;
|
||||||
AControl: TControl absolute AnObject;
|
AControl: TControl absolute AnObject;
|
||||||
AContainer: TControl;
|
AContainer: TPersistent;
|
||||||
AcceptControl, AcceptContainer: Boolean;
|
AcceptControl, AcceptContainer: Boolean;
|
||||||
InsertType: TTreeViewInsertMarkType;
|
InsertType: TTreeViewInsertMarkType;
|
||||||
ParentNode: TTreeNode;
|
ParentNode: TTreeNode;
|
||||||
@ -353,10 +389,17 @@ begin
|
|||||||
(AControl.Owner.Owner = nil) // child of a root
|
(AControl.Owner.Owner = nil) // child of a root
|
||||||
) then
|
) then
|
||||||
begin
|
begin
|
||||||
AContainer := TWinControl(AnObject);
|
AContainer := TPersistent(AnObject);
|
||||||
//DebugLn(['TComponentTreeView.DragOver AContainer=',DbgSName(AContainer)]);
|
//DebugLn(['TComponentTreeView.DragOver AContainer=',DbgSName(AContainer)]);
|
||||||
AcceptContainer := True;
|
AcceptContainer := True;
|
||||||
end;
|
end;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if (AnObject is TCollection) then
|
||||||
|
begin
|
||||||
|
// it is allowed to move container items inside the container
|
||||||
|
AContainer := TPersistent(AnObject);
|
||||||
|
AcceptContainer := True;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -367,20 +410,31 @@ begin
|
|||||||
begin
|
begin
|
||||||
AnObject := TObject(Node.Data);
|
AnObject := TObject(Node.Data);
|
||||||
// don't allow to move ancestor components
|
// don't allow to move ancestor components
|
||||||
if (AnObject is TComponent) and (csAncestor in TComponent(AnObject).ComponentState) then break;
|
if (AnObject is TComponent) and
|
||||||
if AnObject is TControl then
|
(csAncestor in TComponent(AnObject).ComponentState) then break;
|
||||||
|
if (AnObject is TControl) then
|
||||||
begin
|
begin
|
||||||
if AControl = AContainer then break;
|
if AnObject = AContainer then break;
|
||||||
|
if not (AContainer is TWinControl) then break;
|
||||||
//DebugLn(['TComponentTreeView.DragOver AControl=',DbgSName(AControl),' Parent=',DbgSName(AControl.Parent),' OldAccepts=',csAcceptsControls in AControl.Parent.ControlStyle]);
|
//DebugLn(['TComponentTreeView.DragOver AControl=',DbgSName(AControl),' Parent=',DbgSName(AControl.Parent),' OldAccepts=',csAcceptsControls in AControl.Parent.ControlStyle]);
|
||||||
// check if new parent allows this control class
|
// check if new parent allows this control class
|
||||||
if not AContainer.CheckChildClassAllowed(AnObject.ClassType, False) then
|
if not TWinControl(AContainer).CheckChildClassAllowed(AnObject.ClassType, False) then
|
||||||
break;
|
break;
|
||||||
// check if one of the parent of the container is the control itself
|
// check if one of the parent of the container is the control itself
|
||||||
if AControl.IsParentOf(AContainer) then break;
|
if AControl.IsParentOf(TWinControl(AContainer)) then break;
|
||||||
// do not move childs of a restricted parent to another parent
|
// do not move children of a restricted parent to another parent
|
||||||
// e.g. TPage of TPageControl
|
// e.g. TPage of TPageControl
|
||||||
if (AControl.Parent<>nil) and (AControl.Parent<>AContainer)
|
if (AControl.Parent <> nil) and (AControl.Parent <> AContainer) and
|
||||||
and (not (csAcceptsControls in AControl.Parent.ControlStyle)) then
|
(not (csAcceptsControls in AControl.Parent.ControlStyle)) then
|
||||||
|
break;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if (AnObject is TCollectionItem) then
|
||||||
|
begin
|
||||||
|
if AnObject = AContainer then break;
|
||||||
|
if not (AContainer is TCollection) then
|
||||||
|
break;
|
||||||
|
if TCollectionItem(AnObject).Collection <> TCollection(AContainer) then
|
||||||
break;
|
break;
|
||||||
end;
|
end;
|
||||||
Node := Node.GetNextMultiSelected;
|
Node := Node.GetNextMultiSelected;
|
||||||
@ -393,8 +447,7 @@ begin
|
|||||||
inherited DragOver(Source, X, Y, State, Accept);
|
inherited DragOver(Source, X, Y, State, Accept);
|
||||||
//debugln('TComponentTreeView.DragOver B ',dbgs(Accept));
|
//debugln('TComponentTreeView.DragOver B ',dbgs(Accept));
|
||||||
|
|
||||||
Accept := AcceptContainer and AcceptControl
|
Accept := AcceptContainer and AcceptControl and ((OnDragOver=nil) or Accept);
|
||||||
and ((OnDragOver=nil) or Accept);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TComponentTreeView.DragCanceled;
|
procedure TComponentTreeView.DragCanceled;
|
||||||
@ -417,11 +470,16 @@ begin
|
|||||||
Node := GetFirstMultiSelected;
|
Node := GetFirstMultiSelected;
|
||||||
if (Node <> nil) and (TObject(Node.Data) is TControl) then
|
if (Node <> nil) and (TObject(Node.Data) is TControl) then
|
||||||
begin
|
begin
|
||||||
// TWinControl allows only to add/remove childs, but not at a specific position
|
// TWinControl allows only to add/remove children, but not at a specific position
|
||||||
AnInsertMarkNode := GetNodeAt(X,Y);
|
AnInsertMarkNode := GetNodeAt(X,Y);
|
||||||
AnInsertMarkType := tvimAsFirstChild;
|
AnInsertMarkType := tvimAsFirstChild;
|
||||||
end else begin
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
GetInsertMarkAt(X, Y, AnInsertMarkNode, AnInsertMarkType);
|
GetInsertMarkAt(X, Y, AnInsertMarkNode, AnInsertMarkType);
|
||||||
|
if (Node <> nil) and (TObject(Node.Data) is TCollectionItem) then
|
||||||
|
if AnInsertMarkType = tvimAsFirstChild then
|
||||||
|
AnInsertMarkType := tvimAsPrevSibling;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user