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 ) takes 1 argument:
- Name - Must match receiver's name to allow dropping
Panel:Receiver( string name, function callback, table menu = nil ) 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:
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
red:
Droppable(
"one-way")
green:
Droppable(
"two-way")
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)
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)