|
|
|
|
//========= Copyright <EFBFBD> 1996-2002, Valve LLC, All rights reserved. ============
|
|
|
|
|
//
|
|
|
|
|
// Purpose:
|
|
|
|
|
//
|
|
|
|
|
// $NoKeywords: $
|
|
|
|
|
//=============================================================================
|
|
|
|
|
|
|
|
|
|
#include "vgui_listbox.h"
|
|
|
|
|
|
|
|
|
|
using namespace vgui;
|
|
|
|
|
|
|
|
|
|
CListBox::CListBox() : Panel( 0, 0, 0, 0 ),
|
|
|
|
|
m_ItemsPanel( 0, 0, 0, 0 ),
|
|
|
|
|
m_ScrollBar( 0, 0, 0, 0, true ),
|
|
|
|
|
m_Slider( 0, 0, 10, 40, true )
|
|
|
|
|
{
|
|
|
|
|
m_Signal.m_pListBox = this;
|
|
|
|
|
|
|
|
|
|
m_ItemsPanel.setParent( this );
|
|
|
|
|
m_ItemsPanel.setBgColor( 0, 0, 0, 255 );
|
|
|
|
|
|
|
|
|
|
m_Slider.setRangeWindow( 50 );
|
|
|
|
|
m_Slider.setRangeWindowEnabled( true );
|
|
|
|
|
|
|
|
|
|
m_ScrollBar.setParent( this );
|
|
|
|
|
m_ScrollBar.addIntChangeSignal( &m_Signal );
|
|
|
|
|
m_ScrollBar.setSlider( &m_Slider );
|
|
|
|
|
m_ScrollBar.setButtonPressedScrollValue( 1 );
|
|
|
|
|
|
|
|
|
|
m_Items.m_pNext = m_Items.m_pPrev = &m_Items;
|
|
|
|
|
m_ItemOffset = 0;
|
|
|
|
|
m_iScrollMax = -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CListBox::~CListBox()
|
|
|
|
|
{
|
|
|
|
|
Term();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CListBox::Init()
|
|
|
|
|
{
|
|
|
|
|
Term();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CListBox::Term()
|
|
|
|
|
{
|
|
|
|
|
m_ItemOffset = 0;
|
|
|
|
|
|
|
|
|
|
// Free the LBItems.
|
|
|
|
|
LBItem *pNext;
|
|
|
|
|
|
|
|
|
|
for( LBItem *pItem =m_Items.m_pNext; pItem != &m_Items; pItem = pNext )
|
|
|
|
|
{
|
|
|
|
|
pItem->m_pPanel->setParent( NULL ); // detach the panel from us
|
|
|
|
|
pNext = pItem->m_pNext;
|
|
|
|
|
delete pItem;
|
|
|
|
|
}
|
|
|
|
|
m_Items.m_pPrev = m_Items.m_pNext = &m_Items;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CListBox::AddItem( Panel *panel )
|
|
|
|
|
{
|
|
|
|
|
// Add the item.
|
|
|
|
|
LBItem *pItem = new LBItem;
|
|
|
|
|
if( !pItem )
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
pItem->m_pPanel = panel;
|
|
|
|
|
pItem->m_pPanel->setParent( &m_ItemsPanel );
|
|
|
|
|
|
|
|
|
|
pItem->m_pPrev = m_Items.m_pPrev;
|
|
|
|
|
pItem->m_pNext = &m_Items;
|
|
|
|
|
pItem->m_pNext->m_pPrev = pItem->m_pPrev->m_pNext = pItem;
|
|
|
|
|
|
|
|
|
|
m_ScrollBar.setRange( 0, GetScrollMax() );
|
|
|
|
|
m_Slider.setRangeWindow( 50 );
|
|
|
|
|
m_Slider.setRangeWindowEnabled( true );
|
|
|
|
|
|
|
|
|
|
InternalLayout();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int CListBox::GetNumItems()
|
|
|
|
|
{
|
|
|
|
|
int count = 0;
|
|
|
|
|
|
|
|
|
|
for( LBItem *pItem = m_Items.m_pNext; pItem != &m_Items; pItem = pItem->m_pNext )
|
|
|
|
|
++count;
|
|
|
|
|
|
|
|
|
|
return count;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int CListBox::GetItemWidth()
|
|
|
|
|
{
|
|
|
|
|
int wide, tall;
|
|
|
|
|
|
|
|
|
|
m_ItemsPanel.getSize( wide, tall );
|
|
|
|
|
|
|
|
|
|
return wide;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int CListBox::GetScrollPos()
|
|
|
|
|
{
|
|
|
|
|
return m_ItemOffset;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CListBox::SetScrollPos( int pos )
|
|
|
|
|
{
|
|
|
|
|
int maxItems = GetScrollMax();
|
|
|
|
|
if( maxItems < 0 )
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
m_ItemOffset = ( pos < 0 ) ? 0 : ( ( pos > maxItems ) ? maxItems : pos );
|
|
|
|
|
InternalLayout();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CListBox::setPos( int x, int y )
|
|
|
|
|
{
|
|
|
|
|
Panel::setPos( x, y );
|
|
|
|
|
InternalLayout();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CListBox::setSize( int wide, int tall )
|
|
|
|
|
{
|
|
|
|
|
Panel::setSize( wide, tall );
|
|
|
|
|
InternalLayout();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CListBox::setPixelScroll( int value )
|
|
|
|
|
{
|
|
|
|
|
m_ItemOffset = m_ScrollBar.getValue();
|
|
|
|
|
InternalLayout();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CListBox::InternalLayout()
|
|
|
|
|
{
|
|
|
|
|
int x, y, wide, tall;
|
|
|
|
|
getBounds( x, y, wide, tall );
|
|
|
|
|
|
|
|
|
|
// Reposition the main panel and the scrollbar.
|
|
|
|
|
m_ItemsPanel.setBounds( 0, 0, wide - 15, tall );
|
|
|
|
|
m_ScrollBar.setBounds( wide - 15, 0, 15, tall );
|
|
|
|
|
|
|
|
|
|
bool bNeedScrollbar = false;
|
|
|
|
|
|
|
|
|
|
// Reposition the items.
|
|
|
|
|
int curItem = 0;
|
|
|
|
|
int curY = 0;
|
|
|
|
|
int maxItem = GetScrollMax();
|
|
|
|
|
for( LBItem *pItem = m_Items.m_pNext; pItem != &m_Items; pItem = pItem->m_pNext )
|
|
|
|
|
{
|
|
|
|
|
if( curItem < m_ItemOffset )
|
|
|
|
|
{
|
|
|
|
|
pItem->m_pPanel->setVisible( false );
|
|
|
|
|
bNeedScrollbar = true;
|
|
|
|
|
}
|
|
|
|
|
else if( curItem >= maxItem )
|
|
|
|
|
{
|
|
|
|
|
// item is past the end of the items we care about
|
|
|
|
|
pItem->m_pPanel->setVisible( false );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
pItem->m_pPanel->setVisible( true );
|
|
|
|
|
|
|
|
|
|
int itemWidth, itemHeight;
|
|
|
|
|
|
|
|
|
|
pItem->m_pPanel->getSize( itemWidth, itemHeight );
|
|
|
|
|
|
|
|
|
|
// Don't change the item's height but change its width to fit the listbox.
|
|
|
|
|
pItem->m_pPanel->setBounds( 0, curY, wide, itemHeight );
|
|
|
|
|
|
|
|
|
|
curY += itemHeight;
|
|
|
|
|
|
|
|
|
|
if( curY > tall )
|
|
|
|
|
{
|
|
|
|
|
bNeedScrollbar = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
++curItem;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_ScrollBar.setVisible( bNeedScrollbar );
|
|
|
|
|
|
|
|
|
|
repaint();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CListBox::paintBackground()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CListBox::SetScrollRange( int maxScroll )
|
|
|
|
|
{
|
|
|
|
|
m_iScrollMax = maxScroll;
|
|
|
|
|
m_ScrollBar.setRange( 0, maxScroll );
|
|
|
|
|
InternalLayout();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int CListBox::GetScrollMax()
|
|
|
|
|
{
|
|
|
|
|
if( m_iScrollMax < 0 )
|
|
|
|
|
{
|
|
|
|
|
return GetNumItems() - 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return m_iScrollMax;
|
|
|
|
|
}
|
|
|
|
|
|