From 39ed87570bdb2f86969d4be821c94b722dc71179 Mon Sep 17 00:00:00 2001 From: Joe Ludwig Date: Wed, 26 Jun 2013 15:22:04 -0700 Subject: First version of the SOurce SDK 2013 --- mp/src/vgui2/vgui_controls/PanelListPanel.cpp | 473 ++++++++++++++++++++++++++ 1 file changed, 473 insertions(+) create mode 100644 mp/src/vgui2/vgui_controls/PanelListPanel.cpp (limited to 'mp/src/vgui2/vgui_controls/PanelListPanel.cpp') diff --git a/mp/src/vgui2/vgui_controls/PanelListPanel.cpp b/mp/src/vgui2/vgui_controls/PanelListPanel.cpp new file mode 100644 index 00000000..5ef40966 --- /dev/null +++ b/mp/src/vgui2/vgui_controls/PanelListPanel.cpp @@ -0,0 +1,473 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include "vgui/MouseCode.h" +#include "vgui/IInput.h" +#include "vgui/IScheme.h" +#include "vgui/ISurface.h" + +#include "vgui_controls/EditablePanel.h" +#include "vgui_controls/ScrollBar.h" +#include "vgui_controls/Label.h" +#include "vgui_controls/Button.h" +#include "vgui_controls/Controls.h" +#include "vgui_controls/PanelListPanel.h" + +#include "KeyValues.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +using namespace vgui; + +//----------------------------------------------------------------------------- +// Purpose: Constructor +//----------------------------------------------------------------------------- +PanelListPanel::PanelListPanel( vgui::Panel *parent, char const *panelName ) : EditablePanel( parent, panelName ) +{ + SetBounds( 0, 0, 100, 100 ); + + m_vbar = new ScrollBar(this, "PanelListPanelVScroll", true); + m_vbar->SetVisible(false); + m_vbar->AddActionSignalTarget( this ); + + m_pPanelEmbedded = new EditablePanel(this, "PanelListEmbedded"); + m_pPanelEmbedded->SetBounds(0, 0, 20, 20); + m_pPanelEmbedded->SetPaintBackgroundEnabled( false ); + m_pPanelEmbedded->SetPaintBorderEnabled(false); + + m_iFirstColumnWidth = 100; // default width + m_iNumColumns = 1; // 1 column by default + + if ( IsProportional() ) + { + m_iDefaultHeight = scheme()->GetProportionalScaledValueEx( GetScheme(), DEFAULT_HEIGHT ); + m_iPanelBuffer = scheme()->GetProportionalScaledValueEx( GetScheme(), PANELBUFFER ); + } + else + { + m_iDefaultHeight = DEFAULT_HEIGHT; + m_iPanelBuffer = PANELBUFFER; + } +} + +//----------------------------------------------------------------------------- +// Purpose: Destructor +//----------------------------------------------------------------------------- +PanelListPanel::~PanelListPanel() +{ + // free data from table + DeleteAllItems(); +} + +void PanelListPanel::SetVerticalBufferPixels( int buffer ) +{ + m_iPanelBuffer = buffer; + InvalidateLayout(); +} + +//----------------------------------------------------------------------------- +// Purpose: counts the total vertical pixels +//----------------------------------------------------------------------------- +int PanelListPanel::ComputeVPixelsNeeded() +{ + int iCurrentItem = 0; + int iLargestH = 0; + + int pixels = 0; + for ( int i = 0; i < m_SortedItems.Count(); i++ ) + { + Panel *panel = m_DataItems[ m_SortedItems[i] ].panel; + if ( !panel ) + continue; + + if ( panel->IsLayoutInvalid() ) + { + panel->InvalidateLayout( true ); + } + + int iCurrentColumn = iCurrentItem % m_iNumColumns; + + int w, h; + panel->GetSize( w, h ); + + if ( iLargestH < h ) + iLargestH = h; + + if ( iCurrentColumn == 0 ) + pixels += m_iPanelBuffer; // add in buffer. between rows. + + if ( iCurrentColumn >= m_iNumColumns - 1 ) + { + pixels += iLargestH; + iLargestH = 0; + } + + iCurrentItem++; + } + + // Add in remaining largest height + pixels += iLargestH; + + pixels += m_iPanelBuffer; // add in buffer below last item + + return pixels; +} + +//----------------------------------------------------------------------------- +// Purpose: Returns the panel to use to render a cell +//----------------------------------------------------------------------------- +Panel *PanelListPanel::GetCellRenderer( int row ) +{ + if ( !m_SortedItems.IsValidIndex(row) ) + return NULL; + + Panel *panel = m_DataItems[ m_SortedItems[row] ].panel; + return panel; +} + +//----------------------------------------------------------------------------- +// Purpose: adds an item to the view +// data->GetName() is used to uniquely identify an item +// data sub items are matched against column header name to be used in the table +//----------------------------------------------------------------------------- +int PanelListPanel::AddItem( Panel *labelPanel, Panel *panel) +{ + Assert(panel); + + if ( labelPanel ) + { + labelPanel->SetParent( m_pPanelEmbedded ); + } + + panel->SetParent( m_pPanelEmbedded ); + + int itemID = m_DataItems.AddToTail(); + DATAITEM &newitem = m_DataItems[itemID]; + newitem.labelPanel = labelPanel; + newitem.panel = panel; + m_SortedItems.AddToTail(itemID); + + InvalidateLayout(); + return itemID; +} + +//----------------------------------------------------------------------------- +// Purpose: iteration accessor +//----------------------------------------------------------------------------- +int PanelListPanel::GetItemCount() const +{ + return m_DataItems.Count(); +} + +int PanelListPanel::GetItemIDFromRow( int nRow ) const +{ + if ( nRow < 0 || nRow >= GetItemCount() ) + return m_DataItems.InvalidIndex(); + return m_SortedItems[ nRow ]; +} + + +//----------------------------------------------------------------------------- +// Iteration. Use these until they return InvalidItemID to iterate all the items. +//----------------------------------------------------------------------------- +int PanelListPanel::FirstItem() const +{ + return m_DataItems.Head(); +} + +int PanelListPanel::NextItem( int nItemID ) const +{ + return m_DataItems.Next( nItemID ); +} + +int PanelListPanel::InvalidItemID() const +{ + return m_DataItems.InvalidIndex( ); +} + + +//----------------------------------------------------------------------------- +// Purpose: returns label panel for this itemID +//----------------------------------------------------------------------------- +Panel *PanelListPanel::GetItemLabel(int itemID) +{ + if ( !m_DataItems.IsValidIndex(itemID) ) + return NULL; + + return m_DataItems[itemID].labelPanel; +} + +//----------------------------------------------------------------------------- +// Purpose: returns label panel for this itemID +//----------------------------------------------------------------------------- +Panel *PanelListPanel::GetItemPanel(int itemID) +{ + if ( !m_DataItems.IsValidIndex(itemID) ) + return NULL; + + return m_DataItems[itemID].panel; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void PanelListPanel::RemoveItem(int itemID) +{ + if ( !m_DataItems.IsValidIndex(itemID) ) + return; + + DATAITEM &item = m_DataItems[itemID]; + if ( item.panel ) + { + item.panel->MarkForDeletion(); + } + if ( item.labelPanel ) + { + item.labelPanel->MarkForDeletion(); + } + + m_DataItems.Remove(itemID); + m_SortedItems.FindAndRemove(itemID); + + InvalidateLayout(); +} + +//----------------------------------------------------------------------------- +// Purpose: clears and deletes all the memory used by the data items +//----------------------------------------------------------------------------- +void PanelListPanel::DeleteAllItems() +{ + FOR_EACH_LL( m_DataItems, i ) + { + if ( m_DataItems[i].panel ) + { + delete m_DataItems[i].panel; + } + } + + m_DataItems.RemoveAll(); + m_SortedItems.RemoveAll(); + + InvalidateLayout(); +} + +//----------------------------------------------------------------------------- +// Purpose: clears and deletes all the memory used by the data items +//----------------------------------------------------------------------------- +void PanelListPanel::RemoveAll() +{ + m_DataItems.RemoveAll(); + m_SortedItems.RemoveAll(); + + // move the scrollbar to the top of the list + m_vbar->SetValue(0); + InvalidateLayout(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void PanelListPanel::OnSizeChanged(int wide, int tall) +{ + BaseClass::OnSizeChanged(wide, tall); + InvalidateLayout(); + Repaint(); +} + +//----------------------------------------------------------------------------- +// Purpose: relayouts out the panel after any internal changes +//----------------------------------------------------------------------------- +void PanelListPanel::PerformLayout() +{ + int wide, tall; + GetSize( wide, tall ); + + int vpixels = ComputeVPixelsNeeded(); + + m_vbar->SetRange( 0, vpixels ); + m_vbar->SetRangeWindow( tall ); + m_vbar->SetButtonPressedScrollValue( tall / 4 ); // standard height of labels/buttons etc. + + m_vbar->SetPos( wide - m_vbar->GetWide() - 2, 0 ); + m_vbar->SetSize( m_vbar->GetWide(), tall - 2 ); + + int top = m_vbar->GetValue(); + + m_pPanelEmbedded->SetPos( 0, -top ); + m_pPanelEmbedded->SetSize( wide - m_vbar->GetWide(), vpixels ); // scrollbar will sit on top (zpos set explicitly) + + bool bScrollbarVisible = true; + // If we're supposed to automatically hide the scrollbar when unnecessary, check it now + if ( m_bAutoHideScrollbar ) + { + bScrollbarVisible = (m_pPanelEmbedded->GetTall() > tall); + } + m_vbar->SetVisible( bScrollbarVisible ); + + // Now lay out the controls on the embedded panel + int y = 0; + int h = 0; + int totalh = 0; + + int xpos = m_iFirstColumnWidth + m_iPanelBuffer; + int iColumnWidth = ( wide - xpos - m_vbar->GetWide() - 12 ) / m_iNumColumns; + + for ( int i = 0; i < m_SortedItems.Count(); i++ ) + { + int iCurrentColumn = i % m_iNumColumns; + + // add in a little buffer between panels + if ( iCurrentColumn == 0 ) + y += m_iPanelBuffer; + + DATAITEM &item = m_DataItems[ m_SortedItems[i] ]; + + if ( h < item.panel->GetTall() ) + h = item.panel->GetTall(); + + if ( item.labelPanel ) + { + item.labelPanel->SetBounds( 0, y, m_iFirstColumnWidth, item.panel->GetTall() ); + } + + item.panel->SetBounds( xpos + iCurrentColumn * iColumnWidth, y, iColumnWidth, item.panel->GetTall() ); + + if ( iCurrentColumn >= m_iNumColumns - 1 ) + { + y += h; + totalh += h; + + h = 0; + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: scheme settings +//----------------------------------------------------------------------------- +void PanelListPanel::ApplySchemeSettings(IScheme *pScheme) +{ + BaseClass::ApplySchemeSettings(pScheme); + + SetBorder(pScheme->GetBorder("ButtonDepressedBorder")); + SetBgColor(GetSchemeColor("ListPanel.BgColor", GetBgColor(), pScheme)); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void PanelListPanel::OnSliderMoved( int position ) +{ + InvalidateLayout(); + Repaint(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void PanelListPanel::MoveScrollBarToTop() +{ + m_vbar->SetValue(0); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void PanelListPanel::SetFirstColumnWidth( int width ) +{ + m_iFirstColumnWidth = width; +} + +//----------------------------------------------------------------------------- +// Purpose: data accessor +//----------------------------------------------------------------------------- +int PanelListPanel::GetFirstColumnWidth() +{ + return m_iFirstColumnWidth; +} + +void PanelListPanel::SetNumColumns( int iNumColumns ) +{ + m_iNumColumns = iNumColumns; +} + +int PanelListPanel::GetNumColumns( void ) +{ + return m_iNumColumns; +} + +//----------------------------------------------------------------------------- +// Purpose: moves the scrollbar with the mousewheel +//----------------------------------------------------------------------------- +void PanelListPanel::OnMouseWheeled(int delta) +{ + int val = m_vbar->GetValue(); + val -= (delta * DEFAULT_HEIGHT); + m_vbar->SetValue(val); +} + +//----------------------------------------------------------------------------- +// Purpose: selection handler +//----------------------------------------------------------------------------- +void PanelListPanel::SetSelectedPanel( Panel *panel ) +{ + if ( panel != m_hSelectedItem ) + { + // notify the panels of the selection change + if ( m_hSelectedItem ) + { + PostMessage( m_hSelectedItem.Get(), new KeyValues("PanelSelected", "state", 0) ); + } + if ( panel ) + { + PostMessage( panel, new KeyValues("PanelSelected", "state", 1) ); + } + m_hSelectedItem = panel; + } +} + +//----------------------------------------------------------------------------- +// Purpose: data accessor +//----------------------------------------------------------------------------- +Panel *PanelListPanel::GetSelectedPanel() +{ + return m_hSelectedItem; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void PanelListPanel::ScrollToItem( int itemNumber ) +{ + if (!m_vbar->IsVisible()) + { + return; + } + + DATAITEM& item = m_DataItems[ m_SortedItems[ itemNumber ] ]; + if ( !item.panel ) + return; + + int x, y; + item.panel->GetPos( x, y ); + int lx, ly; + lx = x; + ly = y; + m_pPanelEmbedded->LocalToScreen( lx, ly ); + ScreenToLocal( lx, ly ); + + int h = item.panel->GetTall(); + + if ( ly >= 0 && ly + h < GetTall() ) + return; + + m_vbar->SetValue( y ); + InvalidateLayout(); +} + + -- cgit v1.2.3