--[[ | This file was obtained through the combined efforts | of Madbluntz & Plymouth Antiquarian Society. | | Credits: lifestorm, Gregory Wayne Rossel JR., | Maloy, DrPepper10 @ RIP, Atle! | | Visit for more: https://plymouth.thetwilightzone.ru/ --]] local PANEL = {} AccessorFunc( PANEL, "m_iOverlap", "Overlap" ) AccessorFunc( PANEL, "m_bShowDropTargets", "ShowDropTargets", FORCE_BOOL ) function PANEL:Init() self.Panels = {} self.OffsetX = 0 self.FrameTime = 0 self.pnlCanvas = vgui.Create( "DDragBase", self ) self.pnlCanvas:SetDropPos( "6" ) self.pnlCanvas:SetUseLiveDrag( false ) self.pnlCanvas.OnModified = function() self:OnDragModified() end self.pnlCanvas.UpdateDropTarget = function( Canvas, drop, pnl ) if ( !self:GetShowDropTargets() ) then return end DDragBase.UpdateDropTarget( Canvas, drop, pnl ) end self.pnlCanvas.OnChildAdded = function( Canvas, child ) local dn = Canvas:GetDnD() if ( dn ) then child:Droppable( dn ) child.OnDrop = function() local x, y = Canvas:LocalCursorPos() local closest, id = self.pnlCanvas:GetClosestChild( x, Canvas:GetTall() / 2 ), 0 for k, v in pairs( self.Panels ) do if ( v == closest ) then id = k break end end table.RemoveByValue( self.Panels, child ) table.insert( self.Panels, id, child ) self:InvalidateLayout() return child end end end self:SetOverlap( 0 ) self.btnLeft = vgui.Create( "DButton", self ) self.btnLeft:SetText( "" ) self.btnLeft.Paint = function( panel, w, h ) derma.SkinHook( "Paint", "ButtonLeft", panel, w, h ) end self.btnRight = vgui.Create( "DButton", self ) self.btnRight:SetText( "" ) self.btnRight.Paint = function( panel, w, h ) derma.SkinHook( "Paint", "ButtonRight", panel, w, h ) end end function PANEL:GetCanvas() return self.pnlCanvas end function PANEL:ScrollToChild( panel ) -- make sure our size is all good self:InvalidateLayout( true ) local x, y = self.pnlCanvas:GetChildPosition( panel ) local w, h = panel:GetSize() x = x + w * 0.5 x = x - self:GetWide() * 0.5 self:SetScroll( x ) end function PANEL:SetScroll( x ) self.OffsetX = x self:InvalidateLayout( true ) end function PANEL:SetUseLiveDrag( bool ) self.pnlCanvas:SetUseLiveDrag( bool ) end function PANEL:MakeDroppable( name, allowCopy ) self.pnlCanvas:MakeDroppable( name, allowCopy ) end function PANEL:AddPanel( pnl ) table.insert( self.Panels, pnl ) pnl:SetParent( self.pnlCanvas ) self:InvalidateLayout( true ) end function PANEL:Clear() self.pnlCanvas:Clear() self.Panels = {} end function PANEL:OnMouseWheeled( dlta ) self.OffsetX = self.OffsetX + dlta * -30 self:InvalidateLayout( true ) return true end function PANEL:Think() -- Hmm.. This needs to really just be done in one place -- and made available to everyone. local FrameRate = VGUIFrameTime() - self.FrameTime self.FrameTime = VGUIFrameTime() if ( self.btnRight:IsDown() ) then self.OffsetX = self.OffsetX + ( 500 * FrameRate ) self:InvalidateLayout( true ) end if ( self.btnLeft:IsDown() ) then self.OffsetX = self.OffsetX - ( 500 * FrameRate ) self:InvalidateLayout( true ) end if ( dragndrop.IsDragging() ) then local x, y = self:LocalCursorPos() if ( x < 30 ) then self.OffsetX = self.OffsetX - ( 350 * FrameRate ) elseif ( x > self:GetWide() - 30 ) then self.OffsetX = self.OffsetX + ( 350 * FrameRate ) end self:InvalidateLayout( true ) end end function PANEL:PerformLayout() local w, h = self:GetSize() self.pnlCanvas:SetTall( h ) local x = 0 for k, v in pairs( self.Panels ) do if ( !IsValid( v ) ) then continue end if ( !v:IsVisible() ) then continue end v:SetPos( x, 0 ) v:SetTall( h ) if ( v.ApplySchemeSettings ) then v:ApplySchemeSettings() end x = x + v:GetWide() - self.m_iOverlap end self.pnlCanvas:SetWide( x + self.m_iOverlap ) if ( w < self.pnlCanvas:GetWide() ) then self.OffsetX = math.Clamp( self.OffsetX, 0, self.pnlCanvas:GetWide() - self:GetWide() ) else self.OffsetX = 0 end self.pnlCanvas.x = self.OffsetX * -1 self.btnLeft:SetSize( 15, 15 ) self.btnLeft:AlignLeft( 4 ) self.btnLeft:AlignBottom( 5 ) self.btnRight:SetSize( 15, 15 ) self.btnRight:AlignRight( 4 ) self.btnRight:AlignBottom( 5 ) self.btnLeft:SetVisible( self.pnlCanvas.x < 0 ) self.btnRight:SetVisible( self.pnlCanvas.x + self.pnlCanvas:GetWide() > self:GetWide() ) end function PANEL:OnDragModified() -- Override me end function PANEL:GenerateExample( classname, sheet, w, h ) local scroller = vgui.Create( "DHorizontalScroller" ) scroller:Dock( TOP ) scroller:SetHeight( 64 ) scroller:DockMargin( 5, 50, 5, 50 ) scroller:SetOverlap( -4 ) for i = 0, 16 do local img = vgui.Create( "DImage", scroller ) img:SetImage( "scripted/breen_fakemonitor_1" ) scroller:AddPanel( img ) end sheet:AddSheet( classname, scroller, nil, true, true ) end derma.DefineControl( "DHorizontalScroller", "", PANEL, "Panel" )