Garry's Mod Wiki

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" />