--[[ | 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_pPropertySheet", "PropertySheet" ) AccessorFunc( PANEL, "m_pPanel", "Panel" ) Derma_Hook( PANEL, "Paint", "Paint", "Tab" ) function PANEL:Init() self:SetMouseInputEnabled( true ) self:SetContentAlignment( 7 ) self:SetTextInset( 0, 4 ) end function PANEL:Setup( label, pPropertySheet, pPanel, strMaterial ) self:SetText( label ) self:SetPropertySheet( pPropertySheet ) self:SetPanel( pPanel ) if ( strMaterial ) then self.Image = vgui.Create( "DImage", self ) self.Image:SetImage( strMaterial ) self.Image:SizeToContents() self:InvalidateLayout() end end function PANEL:IsActive() return self:GetPropertySheet():GetActiveTab() == self end function PANEL:DoClick() self:GetPropertySheet():SetActiveTab( self ) end function PANEL:PerformLayout() self:ApplySchemeSettings() if ( !self.Image ) then return end self.Image:SetPos( 7, 3 ) if ( !self:IsActive() ) then self.Image:SetImageColor( Color( 255, 255, 255, 155 ) ) else self.Image:SetImageColor( color_white ) end end function PANEL:UpdateColours( skin ) if ( self:IsActive() ) then if ( self:GetDisabled() ) then return self:SetTextStyleColor( skin.Colours.Tab.Active.Disabled ) end if ( self:IsDown() ) then return self:SetTextStyleColor( skin.Colours.Tab.Active.Down ) end if ( self.Hovered ) then return self:SetTextStyleColor( skin.Colours.Tab.Active.Hover ) end return self:SetTextStyleColor( skin.Colours.Tab.Active.Normal ) end if ( self:GetDisabled() ) then return self:SetTextStyleColor( skin.Colours.Tab.Inactive.Disabled ) end if ( self:IsDown() ) then return self:SetTextStyleColor( skin.Colours.Tab.Inactive.Down ) end if ( self.Hovered ) then return self:SetTextStyleColor( skin.Colours.Tab.Inactive.Hover ) end return self:SetTextStyleColor( skin.Colours.Tab.Inactive.Normal ) end function PANEL:GetTabHeight() if ( self:IsActive() ) then return 28 else return 20 end end function PANEL:ApplySchemeSettings() local ExtraInset = 10 if ( self.Image ) then ExtraInset = ExtraInset + self.Image:GetWide() end self:SetTextInset( ExtraInset, 4 ) local w, h = self:GetContentSize() h = self:GetTabHeight() self:SetSize( w + 10, h ) DLabel.ApplySchemeSettings( self ) end -- -- DragHoverClick -- function PANEL:DragHoverClick( HoverTime ) self:DoClick() end function PANEL:GenerateExample() -- Do nothing! end function PANEL:DoRightClick() if ( !IsValid( self:GetPropertySheet() ) ) then return end local tabs = DermaMenu() for k, v in pairs( self:GetPropertySheet().Items ) do if ( !v || !IsValid( v.Tab ) || !v.Tab:IsVisible() ) then continue end local option = tabs:AddOption( v.Tab:GetText(), function() if ( !v || !IsValid( v.Tab ) || !IsValid( self:GetPropertySheet() ) || !IsValid( self:GetPropertySheet().tabScroller ) ) then return end v.Tab:DoClick() self:GetPropertySheet().tabScroller:ScrollToChild( v.Tab ) end ) if ( IsValid( v.Tab.Image ) ) then option:SetIcon( v.Tab.Image:GetImage() ) end end tabs:Open() end derma.DefineControl( "DTab", "A Tab for use on the PropertySheet", PANEL, "DButton" ) --[[--------------------------------------------------------- DPropertySheet -----------------------------------------------------------]] local PANEL = {} Derma_Hook( PANEL, "Paint", "Paint", "PropertySheet" ) AccessorFunc( PANEL, "m_pActiveTab", "ActiveTab" ) AccessorFunc( PANEL, "m_iPadding", "Padding" ) AccessorFunc( PANEL, "m_fFadeTime", "FadeTime" ) AccessorFunc( PANEL, "m_bShowIcons", "ShowIcons" ) function PANEL:Init() self:SetShowIcons( true ) self.tabScroller = vgui.Create( "DHorizontalScroller", self ) self.tabScroller:SetOverlap( 5 ) self.tabScroller:Dock( TOP ) self.tabScroller:DockMargin( 3, 0, 3, 0 ) self:SetFadeTime( 0.1 ) self:SetPadding( 8 ) self.animFade = Derma_Anim( "Fade", self, self.CrossFade ) self.Items = {} end function PANEL:AddSheet( label, panel, material, NoStretchX, NoStretchY, Tooltip ) if ( !IsValid( panel ) ) then ErrorNoHalt( "DPropertySheet:AddSheet tried to add invalid panel!" ) debug.Trace() return end local Sheet = {} Sheet.Name = label Sheet.Tab = vgui.Create( "DTab", self ) Sheet.Tab:SetTooltip( Tooltip ) Sheet.Tab:Setup( label, self, panel, material ) Sheet.Panel = panel Sheet.Panel.NoStretchX = NoStretchX Sheet.Panel.NoStretchY = NoStretchY Sheet.Panel:SetPos( self:GetPadding(), 20 + self:GetPadding() ) Sheet.Panel:SetVisible( false ) panel:SetParent( self ) table.insert( self.Items, Sheet ) if ( !self:GetActiveTab() ) then self:SetActiveTab( Sheet.Tab ) Sheet.Panel:SetVisible( true ) end self.tabScroller:AddPanel( Sheet.Tab ) return Sheet end function PANEL:SetActiveTab( active ) if ( !IsValid( active ) || self.m_pActiveTab == active ) then return end if ( IsValid( self.m_pActiveTab ) ) then -- Only run this callback when we actually switch a tab, not when a tab is initially set active self:OnActiveTabChanged( self.m_pActiveTab, active ) if ( self:GetFadeTime() > 0 ) then self.animFade:Start( self:GetFadeTime(), { OldTab = self.m_pActiveTab, NewTab = active } ) else self.m_pActiveTab:GetPanel():SetVisible( false ) end end self.m_pActiveTab = active self:InvalidateLayout() end function PANEL:OnActiveTabChanged( old, new ) -- For override end function PANEL:Think() self.animFade:Run() end function PANEL:GetItems() return self.Items end function PANEL:CrossFade( anim, delta, data ) if ( !data || !IsValid( data.OldTab ) || !IsValid( data.NewTab ) ) then return end local old = data.OldTab:GetPanel() local new = data.NewTab:GetPanel() if ( !IsValid( old ) && !IsValid( new ) ) then return end if ( anim.Finished ) then if ( IsValid( old ) ) then old:SetAlpha( 255 ) old:SetZPos( 0 ) old:SetVisible( false ) end if ( IsValid( new ) ) then new:SetAlpha( 255 ) new:SetZPos( 0 ) new:SetVisible( true ) -- In case new == old end return end if ( anim.Started ) then if ( IsValid( old ) ) then old:SetAlpha( 255 ) old:SetZPos( 0 ) end if ( IsValid( new ) ) then new:SetAlpha( 0 ) new:SetZPos( 1 ) end end if ( IsValid( old ) ) then old:SetVisible( true ) if ( !IsValid( new ) ) then old:SetAlpha( 255 * ( 1 - delta ) ) end end if ( IsValid( new ) ) then new:SetVisible( true ) new:SetAlpha( 255 * delta ) end end function PANEL:PerformLayout() local ActiveTab = self:GetActiveTab() local Padding = self:GetPadding() if ( !IsValid( ActiveTab ) ) then return end -- Update size now, so the height is definitiely right. ActiveTab:InvalidateLayout( true ) --self.tabScroller:StretchToParent( Padding, 0, Padding, nil ) self.tabScroller:SetTall( ActiveTab:GetTall() ) local ActivePanel = ActiveTab:GetPanel() for k, v in pairs( self.Items ) do if ( v.Tab:GetPanel() == ActivePanel ) then if ( IsValid( v.Tab:GetPanel() ) ) then v.Tab:GetPanel():SetVisible( true ) end v.Tab:SetZPos( 100 ) else if ( IsValid( v.Tab:GetPanel() ) ) then v.Tab:GetPanel():SetVisible( false ) end v.Tab:SetZPos( 1 ) end v.Tab:ApplySchemeSettings() end if ( IsValid( ActivePanel ) ) then if ( !ActivePanel.NoStretchX ) then ActivePanel:SetWide( self:GetWide() - Padding * 2 ) else ActivePanel:CenterHorizontal() end if ( !ActivePanel.NoStretchY ) then local _, y = ActivePanel:GetPos() ActivePanel:SetTall( self:GetTall() - y - Padding ) else ActivePanel:CenterVertical() end ActivePanel:InvalidateLayout() end -- Give the animation a chance self.animFade:Run() end function PANEL:SizeToContentWidth() local wide = 0 for k, v in pairs( self.Items ) do if ( IsValid( v.Panel ) ) then v.Panel:InvalidateLayout( true ) wide = math.max( wide, v.Panel:GetWide() + self:GetPadding() * 2 ) end end self:SetWide( wide ) end function PANEL:SwitchToName( name ) for k, v in pairs( self.Items ) do if ( v.Name == name ) then v.Tab:DoClick() return true end end return false end function PANEL:SetupCloseButton( func ) self.CloseButton = self.tabScroller:Add( "DImageButton" ) self.CloseButton:SetImage( "icon16/circlecross.png" ) self.CloseButton:SetColor( Color( 10, 10, 10, 200 ) ) self.CloseButton:DockMargin( 1, 1, 1, 9 ) self.CloseButton:SetWide( 18 ) self.CloseButton:Dock( RIGHT ) self.CloseButton.DoClick = function() if ( func ) then func() end end end function PANEL:CloseTab( tab, bRemovePanelToo ) for k, v in pairs( self.Items ) do if ( v.Tab != tab ) then continue end table.remove( self.Items, k ) end for k, v in pairs( self.tabScroller.Panels ) do if ( v != tab ) then continue end table.remove( self.tabScroller.Panels, k ) end self.tabScroller:InvalidateLayout( true ) if ( tab == self:GetActiveTab() ) then self.m_pActiveTab = self.Items[ #self.Items ].Tab end local pnl = tab:GetPanel() if ( bRemovePanelToo ) then pnl:Remove() end tab:Remove() self:InvalidateLayout( true ) return pnl end derma.DefineControl( "DPropertySheet", "", PANEL, "Panel" )