--[[ | 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/ --]] do local PANEL = vgui.Register("pac_horizontal_scrollbar", {}, "Panel") AccessorFunc( PANEL, "m_HideButtons", "HideButtons" ) function PANEL:Init() self.Offset = 0 self.Scroll = 0 self.CanvasSize = 1 self.BarSize = 1 self.btnLeft = vgui.Create( "DButton", self ) self.btnLeft:SetText( "" ) self.btnLeft.DoClick = function( self ) self:GetParent():AddScroll( -1 ) end 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.DoClick = function( self ) self:GetParent():AddScroll( 1 ) end self.btnRight.Paint = function( panel, w, h ) derma.SkinHook( "Paint", "ButtonRight", panel, w, h ) end self.btnGrip = vgui.Create( "DScrollBarGrip", self ) self.btnGrip.Paint = function(panel,w,h) local skin = panel:GetSkin() if ( panel:GetDisabled() ) then skin.tex.Scroller.ButtonH_Disabled( 0, 0, w, h ) elseif ( panel.Depressed ) then return skin.tex.Scroller.ButtonH_Down( 0, 0, w, h ) elseif ( panel.Hovered ) then return skin.tex.Scroller.ButtonH_Hover( 0, 0, w, h ) else skin.tex.Scroller.ButtonH_Normal( 0, 0, w, h ) end return true end self:SetSize( 15, 15 ) self:SetHideButtons( false ) end function PANEL:SetEnabled( b ) if ( !b ) then self.Offset = 0 self:SetScroll( 0 ) self.HasChanged = true end self:SetMouseInputEnabled( b ) self:SetVisible( b ) -- We're probably changing the width of something in our parent -- by appearing or hiding, so tell them to re-do their layout. if ( self.Enabled != b ) then self:GetParent():InvalidateLayout() if ( self:GetParent().OnScrollbarAppear ) then self:GetParent():OnScrollbarAppear() end end self.Enabled = b end function PANEL:Value() return self.Pos end function PANEL:BarScale() if ( self.BarSize == 0 ) then return 1 end return self.BarSize / ( self.CanvasSize + self.BarSize ) end function PANEL:SetUp( _barsize_, _canvassize_ ) self.BarSize = _barsize_ self.CanvasSize = math.max( _canvassize_ - _barsize_, 1 ) self:SetEnabled( _canvassize_ > _barsize_ ) self:InvalidateLayout() end function PANEL:OnMouseWheeled( dlta ) if ( !self:IsVisible() ) then return false end -- We return true if the scrollbar changed. -- If it didn't, we feed the mousehweeling to the parent panel return self:AddScroll( dlta * -2 ) end function PANEL:AddScroll( dlta ) local OldScroll = self:GetScroll() dlta = dlta * 25 self:SetScroll( self:GetScroll() + dlta ) return OldScroll != self:GetScroll() end function PANEL:SetScroll( scrll ) if ( !self.Enabled ) then self.Scroll = 0 return end self.Scroll = math.Clamp( scrll, 0, self.CanvasSize ) self:InvalidateLayout() -- If our parent has a OnVScroll function use that, if -- not then invalidate layout (which can be pretty slow) local func = self:GetParent().OnVScroll if ( func ) then func( self:GetParent(), self:GetOffset() ) else self:GetParent():InvalidateLayout() end end function PANEL:AnimateTo( scrll, length, delay, ease ) local anim = self:NewAnimation( length, delay, ease ) anim.StartPos = self.Scroll anim.TargetPos = scrll anim.Think = function( anim, pnl, fraction ) pnl:SetScroll( Lerp( fraction, anim.StartPos, anim.TargetPos ) ) end end function PANEL:GetScroll() if ( !self.Enabled ) then self.Scroll = 0 end return self.Scroll end function PANEL:GetOffset() if ( !self.Enabled ) then return 0 end return self.Scroll * -1 end function PANEL:Think() end function PANEL:Paint( w, h ) self:GetSkin().tex.Scroller.TrackH(0,0,w,h) return true end function PANEL:OnMousePressed() local x, y = self:CursorPos() local PageSize = self.BarSize if ( x > self.btnGrip.x ) then self:SetScroll( self:GetScroll() + PageSize ) else self:SetScroll( self:GetScroll() - PageSize ) end end function PANEL:OnMouseReleased() self.Dragging = false self.DraggingCanvas = nil self:MouseCapture( false ) self.btnGrip.Depressed = false end function PANEL:OnCursorMoved( x, y ) if ( !self.Enabled ) then return end if ( !self.Dragging ) then return end local x, y = self:ScreenToLocal( gui.MouseX(), 0 ) -- Uck. x = x - self.btnLeft:GetWide() x = x - self.HoldPos local BtnHeight = self:GetTall() if ( self:GetHideButtons() ) then BtnHeight = 0 end local TrackSize = self:GetWide() - BtnHeight * 2 - self.btnGrip:GetWide() x = x / TrackSize self:SetScroll( x * self.CanvasSize ) end function PANEL:Grip() if ( !self.Enabled ) then return end if ( self.BarSize == 0 ) then return end self:MouseCapture( true ) self.Dragging = true local x, y = self.btnGrip:ScreenToLocal( gui.MouseX(), 0 ) self.HoldPos = x self.btnGrip.Depressed = true end function PANEL:PerformLayout() local Wide = self:GetTall() local BtnHeight = Wide if ( self:GetHideButtons() ) then BtnHeight = 0 end local Scroll = self:GetScroll() / self.CanvasSize local BarSize = math.max( self:BarScale() * ( self:GetWide() - ( BtnHeight * 2 ) ), 10 ) local Track = self:GetWide() - ( BtnHeight * 2 ) - BarSize Track = Track + 1 Scroll = Scroll * Track self.btnGrip:SetPos( BtnHeight + Scroll, 0 ) self.btnGrip:SetSize( BarSize, Wide ) if ( BtnHeight > 0 ) then self.btnLeft:SetPos( 0, 0, Wide, Wide ) self.btnLeft:SetSize( BtnHeight, Wide ) self.btnRight:SetPos( self:GetWide() - BtnHeight, 0 ) self.btnRight:SetSize(BtnHeight, Wide ) self.btnLeft:SetVisible( true ) self.btnRight:SetVisible( true ) else self.btnLeft:SetVisible( false ) self.btnRight:SetVisible( false ) self.btnRight:SetSize( BtnHeight, Wide ) self.btnLeft:SetSize( BtnHeight, Wide ) end end end do local PANEL = vgui.Register("pac_scrollpanel_horizontal", {}, "DPanel") AccessorFunc( PANEL, "Padding", "Padding" ) AccessorFunc( PANEL, "pnlCanvas", "Canvas" ) function PANEL:Init() self.pnlCanvas = vgui.Create( "Panel", self ) self.pnlCanvas.OnMousePressed = function( self, code ) self:GetParent():OnMousePressed( code ) end self.pnlCanvas:SetMouseInputEnabled( true ) self.pnlCanvas.PerformLayout = function( pnl ) self:PerformLayout() self:InvalidateParent() end -- Create the scroll bar self.VBar = vgui.Create( "pac_horizontal_scrollbar", self ) self.VBar:Dock( BOTTOM ) self:SetPadding( 0 ) self:SetMouseInputEnabled( true ) -- This turns off the engine drawing self:SetPaintBackgroundEnabled( false ) self:SetPaintBorderEnabled( false ) self:SetPaintBackground( false ) end function PANEL:AddItem( pnl ) pnl:SetParent( self:GetCanvas() ) end function PANEL:OnChildAdded( child ) self:AddItem( child ) end function PANEL:SizeToContents() self:SetSize( self.pnlCanvas:GetSize() ) end function PANEL:GetVBar() return self.VBar end function PANEL:GetCanvas() return self.pnlCanvas end function PANEL:InnerWidth() return self:GetCanvas():GetTall() end function PANEL:Rebuild() self:GetCanvas():SizeToChildren( true, false ) -- Although this behaviour isn't exactly implied, center vertically too if ( self.m_bNoSizing && self:GetCanvas():GetWide() < self:GetWide() ) then self:GetCanvas():SetPos( ( self:GetWide() - self:GetCanvas():GetWide() ) * 0.5, 0 ) end end function PANEL:OnMouseWheeled( dlta ) return self.VBar:OnMouseWheeled( dlta ) end function PANEL:OnVScroll( iOffset ) self.pnlCanvas:SetPos( iOffset, 0 ) end function PANEL:ScrollToChild( panel ) self:PerformLayout() local x, y = self.pnlCanvas:GetChildPosition( panel ) local w, h = panel:GetSize() x = x + w * 0.5 x = x - self:GetWide() * 0.5 self.VBar:AnimateTo( x, 0.5, 0, 0.5 ) end function PANEL:PerformLayout() local Tall = self.pnlCanvas:GetWide() local Wide = self:GetWide() local YPos = 0 self:Rebuild() self.VBar:SetUp( self:GetWide(), self.pnlCanvas:GetWide() ) YPos = self.VBar:GetOffset() if ( self.VBar.Enabled ) then Wide = Wide - self.VBar:GetWide() end self.pnlCanvas:SetPos( YPos, 0 ) self.pnlCanvas:SetWide( Wide ) self:Rebuild() if ( Tall != self.pnlCanvas:GetWide() ) then self.VBar:SetScroll( self.VBar:GetScroll() ) -- Make sure we are not too far down! end end function PANEL:Clear() return self.pnlCanvas:Clear() end end