Revision Difference
Drag_and_Drop_for_VGUI#562997
<cat>Dev.UI</cat>⤶
# Drag 'N' Drop
This is a drag n drop tutorial since it's barely documented.
It's very easy, all you need to have is two panels: a receiver and a droppable panel.
## How it Works
[Panel:Droppable( string name )](https://wiki.facepunch.com/gmod/Panel:Droppable) takes 1 argument:
* Name - Must match receiver's name to allow dropping
[Panel:Receiver( string name, function callback, table menu = nil )](https://wiki.facepunch.com/gmod/Panel:Receiver) takes 3 arguments:
* Name - Identifier to match droppable panels
* Callback - Function called when dragging/dropping occurs
* Menu Options - Table of strings for right-click menu (optional)
The callback receives:
* self - The receiving panel
* panels - Table of panels being dropped
* dropped - True when actually dropped, false while dragging over
* menuIndex - Index if using right-click menu
* x,y - Drop coordinates relative to receiver
In the example below:
* Red panel can only be dropped on right frame
* Green panel can be dropped on either frame
* When dropped, panels become children of the receiving frame
## Basic Example
Here's a complete example showing one-way and two-way drag and drop:
```lua
-- Create two frames side by side
local left_dframe = vgui.Create("DFrame")
local right_dframe = vgui.Create("DFrame")
local w, h = 200, 300
local screen_w, screen_h = ScrW(), ScrH()
local x = screen_w / 2 - w - 10
local y = screen_h / 2 - h / 2
left_dframe:SetSize(w, h)
right_dframe:SetSize(w, h)
left_dframe:SetPos(x, y)
right_dframe:SetPos(x + w + 20, y)
left_dframe:SetTitle("Source")
right_dframe:SetTitle("Target")
left_dframe:MakePopup()
right_dframe:MakePopup()
local red = vgui.Create("DPanel", left_dframe)
local green = vgui.Create("DPanel", left_dframe)
red:SetSize(50, 50)
green:SetSize(50, 50)
red:SetPos(20, 50)
green:SetPos(20, 120)
red.Paint = function(s, w, h)
surface.SetDrawColor(120, 0, 0)
surface.DrawRect(0, 0, w, h)
draw.DrawText("One-way", "DermaDefault", w / 2, h / 2, color_white, TEXT_ALIGN_CENTER)
end
green.Paint = function(s, w, h)
surface.SetDrawColor(0, 120, 0)
surface.DrawRect(0, 0, w, h)
draw.DrawText("Two-way", "DermaDefault", w / 2, h / 2, color_white, TEXT_ALIGN_CENTER)
end
-- Make panels draggable
red:Droppable("one-way")
green:Droppable("two-way")
-- Make only right dframe receive one-way drops
right_dframe:Receiver("one-way", function(self, panels, dropped, _, x, y)
if dropped then
panels[1]:SetParent(self)
panels[1]:SetPos(x - 25, y - 25)
end
end)
-- Make both dframes receive two-way drops
right_dframe:Receiver("two-way", function(self, panels, dropped, _, x, y)
if dropped then
panels[1]:SetParent(self)
panels[1]:SetPos(x - 25, y - 25)
end
end)
left_dframe:Receiver("two-way", function(self, panels, dropped, _, x, y)
if dropped then
panels[1]:SetParent(self)
panels[1]:SetPos(x - 25, y - 25)
end
end)
```
<upload src="b5453/8dd0e1a9b8d45b1.gif" size="4926499" name="ezgif-2-7f57a61ca1.gif" />