Search code examples
delphidrag-and-dropdocking

Is this possible in Delphi Docking or does it need custom Drag and Drop?


Please refer to the following picture:

  • Panel1 and Panel2 are dockable.
  • The panel on the right is dock site.
  • I know how the default docking works when you drag panel1 and panel2 one by one to the right panel.

enter image description here

My question: Can I control the docking preview rectangle and final docking rectangle so that the docked panel retains its height and occupies full width of the right panel? In other words, can I create a snap-in type effect where on docking the first panel, it sits at the top of the right panel with its own height. Then the second panel when docked snaps-in below it with its own height?

I suspect that I will need to use my own Drag and Drop instead of docking to do that kind of drag and drop snapping in place. I wanted to use Docking because of its nice target preview rectangle feature for which I will have to do my own code in Drag and Drop.


Solution

  • Here is an example of you can achieve this

    procedure TForm3.ScrollBox1DockDrop(Sender: TObject; Source: TDragDockObject; X,
      Y: Integer);
    begin
      //Change the dropped component (source) Align property to alTop to achieve top 
      //alignment of docked control
      Source.Control.Align := alTop;
    end;
    
    procedure TForm3.ScrollBox1UnDock(Sender: TObject; Client: TControl;
      NewTarget: TWinControl; var Allow: Boolean);
    begin
      //Reset Align property to alNone to revert undocked control to original size
      //NOTE: Changing Source.DocRect like in OnDockOver event below will also change
      //original size of the control. So when undocked it will no longer have same 
      //dimensions as it did before docking 
    
      Client.Align := alNone;
    end;
    
    //Here we can manipulate the size of DockRect to get better preview of docked component.
    //NOTE: Changing Source.DocRect like in OnDockOver event below will also change
    //original size of the control. So when undocked it will no longer have same 
    //dimensions as it did before docking
    procedure TForm3.ScrollBox1DockOver(Sender: TObject; Source: TDragDockObject; X,
      Y: Integer; State: TDragState; var Accept: Boolean);
    var
      ARect: TRect;
    begin
      Accept := Source.Control is TPanel;
      if Accept then
      begin
        ARect.TopLeft := (Sender as TScrollBox).ClientToScreen(Point(0,Y));
        ARect.BottomRight := (Sender as TScrollBox).ClientToScreen(Point((Sender as TScrollBox).ClientWidth, Source.Control.Height+Y));
        Source.DockRect := ARect;
      end;
    end;
    

    Also you might want to check this question for more information about docking including suggestions for some third party components

    How do I make dockable forms like the IDE's without the very slow freezing movement of the dockable form?