|
|
//========= Copyright Valve Corporation, All rights reserved. ============//
//
//=============================================================================
// Valve includes
#include "tier1/KeyValues.h"
#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"
// Local includes
#include "dualpanellist.h"
// Last include
#include "tier0/memdbgon.h"
//=============================================================================
//
//=============================================================================
CDualPanelList::CDualPanelList( vgui::Panel *pParent, char const *pszPanelName ) : vgui::Panel( pParent, pszPanelName ) , m_pScrollBar( NULL ) { SetBounds( 0, 0, 100, 100 );
if ( false ) { m_pScrollBar = new vgui::ScrollBar( this, "CDualPanelListVScroll", true ); m_pScrollBar->AddActionSignalTarget( this ); }
m_pPanelEmbedded = new vgui::EditablePanel( this, "PanelListEmbedded" ); m_pPanelEmbedded->SetBounds( 0, 0, 20, 20 ); m_pPanelEmbedded->SetPaintBackgroundEnabled( false ); m_pPanelEmbedded->SetPaintBorderEnabled( false );
m_iFirstColumnWidth = 100; // default width
m_nNumColumns = 1; // 1 column by default
if ( false && IsProportional() ) { m_iDefaultHeight = vgui::scheme()->GetProportionalScaledValueEx( GetScheme(), DEFAULT_HEIGHT ); m_iPanelBuffer = vgui::scheme()->GetProportionalScaledValueEx( GetScheme(), PANELBUFFER ); } else { m_iDefaultHeight = DEFAULT_HEIGHT; m_iPanelBuffer = PANELBUFFER; } }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
CDualPanelList::~CDualPanelList() { // free data from table
DeleteAllItems(); }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDualPanelList::SetVerticalBufferPixels( int buffer ) { m_iPanelBuffer = buffer; InvalidateLayout(); }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
int CDualPanelList::ComputeVPixelsNeeded() { int iCurrentItem = 0; int iLargestH = 0;
int nPixels = 0; for ( int i = 0; i < m_SortedItems.Count(); i++ ) { Panel *pPanel = m_DataItems[ m_SortedItems[i] ].panel; if ( !pPanel || !pPanel->IsVisible() ) continue;
if ( pPanel->IsLayoutInvalid() ) { pPanel->InvalidateLayout( true ); }
int iCurrentColumn = iCurrentItem % m_nNumColumns;
int w, h; pPanel->GetSize( w, h );
if ( iLargestH < h ) iLargestH = h;
if ( iCurrentColumn == 0 ) nPixels += m_iPanelBuffer; // add in buffer. between rows.
if ( iCurrentColumn >= m_nNumColumns - 1 ) { nPixels += iLargestH; iLargestH = 0; }
iCurrentItem++; }
// Add in remaining largest height
nPixels += iLargestH;
nPixels += m_iPanelBuffer; // add in buffer below last item
/*
nPixels = 0; for ( int i = 0; i < m_SortedItems.Count(); ++i ) { Panel *pPanel = m_DataItems[ m_SortedItems[i] ].panel; if ( !pPanel ) continue;
int nWide = 0; int nHeight = 0; pPanel->GetSize( nWide, nHeight );
nPixels += nHeight; } */
return nPixels; }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
vgui::Panel *CDualPanelList::GetCellRenderer( int row ) { if ( !m_SortedItems.IsValidIndex(row) ) return NULL;
Panel *panel = m_DataItems[ m_SortedItems[row] ].panel; return panel; }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
int CDualPanelList::AddItem( vgui::Panel *labelPanel, vgui::Panel *panel) { Assert(panel);
if ( labelPanel ) { labelPanel->SetParent( m_pPanelEmbedded ); }
panel->SetParent( m_pPanelEmbedded );
int itemID = m_DataItems.AddToTail(); CDataItem &newitem = m_DataItems[itemID]; newitem.labelPanel = labelPanel; newitem.panel = panel; m_SortedItems.AddToTail(itemID);
InvalidateLayout(); return itemID; }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
int CDualPanelList::GetItemCount() const { return m_DataItems.Count(); }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
int CDualPanelList::GetItemIDFromRow( int nRow ) const { if ( nRow < 0 || nRow >= GetItemCount() ) return m_DataItems.InvalidIndex();
return m_SortedItems[ nRow ]; }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
int CDualPanelList::FirstItem() const { return m_DataItems.Head(); }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
int CDualPanelList::NextItem( int nItemID ) const { return m_DataItems.Next( nItemID ); }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
int CDualPanelList::InvalidItemID() const { return m_DataItems.InvalidIndex(); }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
vgui::Panel *CDualPanelList::GetItemLabel(int nItemID) { if ( !m_DataItems.IsValidIndex( nItemID ) ) return NULL;
return m_DataItems[nItemID].labelPanel; }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
vgui::Panel *CDualPanelList::GetItemPanel( int nItemID ) { if ( !m_DataItems.IsValidIndex( nItemID ) ) return NULL;
return m_DataItems[nItemID].panel; }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
bool CDualPanelList::IsItemVisible( int nItemID ) const { if ( !m_DataItems.IsValidIndex( nItemID ) ) return true;
return m_DataItems[nItemID].IsVisible(); }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDualPanelList::SetItemVisible( int nItemID, bool bVisible ) { if ( !m_DataItems.IsValidIndex( nItemID ) ) return;
m_DataItems[nItemID].SetVisible( bVisible );
InvalidateLayout(); }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDualPanelList::RemoveItem( int nItemID ) { if ( !m_DataItems.IsValidIndex( nItemID ) ) return;
CDataItem &item = m_DataItems[nItemID]; if ( item.panel ) { item.panel->MarkForDeletion(); }
if ( item.labelPanel ) { item.labelPanel->MarkForDeletion(); }
m_DataItems.Remove( nItemID ); m_SortedItems.FindAndRemove( nItemID );
InvalidateLayout(); }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDualPanelList::DeleteAllItems() { FOR_EACH_LL( m_DataItems, i ) { if ( m_DataItems[i].panel ) { delete m_DataItems[i].panel; } }
m_DataItems.RemoveAll(); m_SortedItems.RemoveAll();
InvalidateLayout(); }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDualPanelList::RemoveAll() { m_DataItems.RemoveAll(); m_SortedItems.RemoveAll();
// m_pScrollBar->SetValue( 0 );
InvalidateLayout(); }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDualPanelList::OnSizeChanged( int nWide, int nTall ) { BaseClass::OnSizeChanged( nWide, nTall ); InvalidateLayout(); Repaint(); }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDualPanelList::PerformLayout() { int nWide, nTall; GetSize( nWide, nTall );
int vpixels = ComputeVPixelsNeeded();
int top = 0; if ( m_pScrollBar ) {
m_pScrollBar->SetRange( 0, vpixels ); m_pScrollBar->SetRangeWindow( nTall ); m_pScrollBar->SetButtonPressedScrollValue( nTall / 4 ); // standard height of labels/buttons etc.
m_pScrollBar->SetPos( nWide - m_pScrollBar->GetWide() - 2, 0 ); m_pScrollBar->SetSize( m_pScrollBar->GetWide(), nTall - 2 );
top = m_pScrollBar->GetValue(); }
m_pPanelEmbedded->SetPos( 1, -top ); if ( m_pScrollBar ) { m_pPanelEmbedded->SetSize( nWide - m_pScrollBar->GetWide() - 2, vpixels ); } else { m_pPanelEmbedded->SetSize( nWide - 2, vpixels ); }
SetSize( nWide, vpixels );
/*
bool bScrollbarVisible = true; // If we're supposed to automatically hide the scrollbar when unnecessary, check it now
if ( m_bAutoHideScrollbar ) { bScrollbarVisible = (m_pPanelEmbedded->GetTall() > nTall); } m_pScrollBar->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 = ( nWide - xpos - 12 ) / m_nNumColumns; if ( m_pScrollBar ) { iColumnWidth = ( nWide - xpos - m_pScrollBar->GetWide() - 12 ) / m_nNumColumns; }
for ( int i = 0; i < m_SortedItems.Count(); i++ ) { CDataItem &item = m_DataItems[ m_SortedItems[i] ]; if ( !item.IsVisible() ) continue;
int iCurrentColumn = i % m_nNumColumns;
// add in a little buffer between panels
if ( iCurrentColumn == 0 ) y += m_iPanelBuffer;
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_nNumColumns - 1 ) { y += h; totalh += h;
h = 0; } } }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDualPanelList::ApplySchemeSettings( vgui::IScheme *pScheme ) { BaseClass::ApplySchemeSettings( pScheme );
SetBorder( pScheme->GetBorder( "ButtonDepressedBorder" ) ); SetBgColor( GetSchemeColor( "ListPanel.BgColor", GetBgColor(), pScheme ) ); }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDualPanelList::OnSliderMoved( int /* nPosition */ ) { InvalidateLayout(); Repaint(); }
/*
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDualPanelList::MoveScrollBarToTop() { m_pScrollBar->SetValue( 0 ); } */
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDualPanelList::SetFirstColumnWidth( int nWidth ) { m_iFirstColumnWidth = nWidth; }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
int CDualPanelList::GetFirstColumnWidth() { return m_iFirstColumnWidth; }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDualPanelList::SetNumColumns( int nNumColumns ) { m_nNumColumns = nNumColumns; }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
int CDualPanelList::GetNumColumns() { return m_nNumColumns; }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDualPanelList::OnMouseWheeled( int nDelta ) { if ( !m_pScrollBar ) return;
int nVal = m_pScrollBar->GetValue(); nVal -= ( nDelta * DEFAULT_HEIGHT ); m_pScrollBar->SetValue( nVal ); }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDualPanelList::SetSelectedPanel( vgui::Panel *pPanel ) { if ( pPanel != m_hSelectedItem ) { // notify the panels of the selection change
if ( m_hSelectedItem ) { PostMessage( m_hSelectedItem.Get(), new KeyValues( "PanelSelected", "state", 0 ) ); }
if ( pPanel ) { PostMessage( pPanel, new KeyValues( "PanelSelected", "state", 1 ) ); }
m_hSelectedItem = pPanel; } }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
vgui::Panel *CDualPanelList::GetSelectedPanel() { return m_hSelectedItem; }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDualPanelList::ScrollToItem( int nItemNumber ) { if ( !m_pScrollBar || !m_pScrollBar->IsVisible() ) return;
CDataItem& item = m_DataItems[ m_SortedItems[ nItemNumber ] ]; 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_pScrollBar->SetValue( y ); InvalidateLayout(); }
|