• Drag n drop and DModelPanel not working properly, how to fix
    7 replies, posted
I had issues with DModelPanel and drag'n'drop not working properly, and I originally was writing this post to get help, but half way underway I found the issue and set out to solve it by myself, I'll post this thread as a guide on how to fix the issue in case anyone Googles this in the future. Inventory slot https://lolihaven.org/13LYy When dragging https://lolihaven.org/FUvR5 The UI structure is as follows Grid layout Grid Box (the name label box) Modelpanel I haven't overwritten the DModelPanel's Paint function, and if I do and just draw a white box, it'll correctly show the white box upon dragging. https://lolihaven.org/Uhsfr My conclusion is that the 3D model itself isn't getting rendered probably, most likely because of the 2D vector being in a relative context normally, but when dragging it should be using a vector in absolute context. So I'll try dragging it to the top left of the screen (closest to 0, 0) https://files.facepunch.com/forum/upload/317874/397ea9d6-52c1-4c09-a2bf-b4b93d7a51b6/image.png As the image demonstrate, my assumption was right. This also confirms that the drag 'n' drop temporary panel is rendered in a global (absolute) context which was pretty obvious considering it doesn't have a parent panel, but proving it will help us understand how to fix it. We have to look at how DModelPanel works and we can look at that here garrysmod/dmodelpanel.lua at master · Facepunch/garrysmod · GitH.. Looking at the rendering process, PANEL:DrawModel is where the rendering of the model happens, and therefore we'll need to change that. First we add a way to identify if the panel is getting dragging. https://lolihaven.org/11x2G Now we have that, we need to alter the rendering process itself. We go down to where it renders the models, which is line 96 on GitHub. We still need to render it the relative model so it doesn't disappear from the grid slot when we drag, and we have to draw another model in an absolute context. https://lolihaven.org/upDfB It should work in theory, now lets test it in practice https://lolihaven.org/kLvPt It works. Please be aware that if you drag it outside the screen (x or y being 0) it wont render. This is most likely due to limitations with the implementation of rendering this, but I'm not sure. Also this code assumes that the panel getting dragged is the parent of the DModelPanel, this might not be the case in your GUI, but feel free to change the code if it doesn't fit your exact uses. Full DrawModel code https://pastebin.com/GShUbEAQ
function PANEL:DrawModel()     local curparent = self     local rightx = self:GetWide()     local leftx = 0     local topy = 0     local bottomy = self:GetTall()     local previous = curparent     if ( curparent:GetParent() == nil ) then -- This is the fix         leftx, topy = self:LocalToScreen( 0, 0 )         rightx, bottomy = self:LocalToScreen( self:GetWide(), self:GetTall() )     end     while ( curparent:GetParent() != nil ) do         curparent = curparent:GetParent()         local x, y = previous:GetPos()         topy = math.max( y, topy + y )         leftx = math.max( x, leftx + x )         bottomy = math.min( y + previous:GetTall(), bottomy + y )         rightx = math.min( x + previous:GetWide(), rightx + x )         previous = curparent     end     render.SetScissorRect( leftx, topy, rightx, bottomy, true )     local ret = self:PreDrawModel( self.Entity )     if ( ret != false ) then         self.Entity:DrawModel()         self:PostDrawModel( self.Entity )     end     render.SetScissorRect( 0, 0, 0, 0, false ) end Here's what seems to be a better solution. I will be including this fix into the game if you cannot find any issues with it.
It only renders the model with relative coordinates https://streamable.com/a1xo7
Seems like an issue with Panel/PaintAt's implementation I may have been needlessly complicated about it, but when I did something similar years ago I just made my own drag-drop system. On pickup I made a complete copy of the element and just moved it in real time. Another possible solution would be to use RTs instead of keeping DModelPanels.
How are you testing it? Because it works for me properly: https://files.facepunch.com/forum/upload/1804/60c61b12-8eda-4a97-99dd-197736d669ca/222222222.gif concommand.Add( "test2", function() local frame = vgui.Create( "DFrame" ) frame:SetSize( 500, 300 ) frame:SetTitle( "Frame" ) frame:MakePopup() frame:Center() local left = vgui.Create( "DScrollPanel", frame ) left:Dock( LEFT ) left:SetWidth( frame:GetWide() / 2 - 7 ) left:SetPaintBackground( true ) left:DockMargin( 0, 0, 4, 0 ) left:Receiver( "myDNDname", DoDrop ) -- Make the panel a receiver for drag and drop events local right = vgui.Create( "DScrollPanel", frame ) right:Dock( FILL ) right:SetPaintBackground( true ) right:Receiver( "myDNDname", DoDrop ) for i = 1, 3 do local but = vgui.Create( "DModelPanel" ) but:SetModel( "models/alyx.mdl" ) but:SetSize( 64, 64 ) but:Dock( TOP ) but:Droppable( "myDNDname" ) -- make the panel be able to be drag'n'dropped onto other panels right:AddItem( but ) end end )
I figure the difference is that the DModelPanels are children of the dragged elements, not the dragged elements
function PANEL:DrawModel() local curparent = self local leftx, topy = self:LocalToScreen( 0, 0 ) local rightx, bottomy = self:LocalToScreen( self:GetWide(), self:GetTall() ) while ( curparent:GetParent() != nil ) do curparent = curparent:GetParent() local x1, y1 = curparent:LocalToScreen( 0, 0 ) local x2, y2 = curparent:LocalToScreen( curparent:GetWide(), curparent:GetTall() ) leftx = math.max( leftx, x1 ) topy = math.max( topy, y1 ) rightx = math.min( rightx, x2 ) bottomy = math.min( bottomy, y2 ) previous = curparent end render.SetScissorRect( leftx, topy, rightx, bottomy, true ) local ret = self:PreDrawModel( self.Entity ) if ( ret != false ) then self.Entity:DrawModel() self:PostDrawModel( self.Entity ) end render.SetScissorRect( 0, 0, 0, 0, false ) end Missed that bit, this should fix that as well as still preserve the ModelPanels in scroll panels not overflowing.
Yep, that works
Sorry, you need to Log In to post a reply to this thread.