You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
589 lines
14 KiB
589 lines
14 KiB
//========= 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(); |
|
}
|
|
|