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.
208 lines
3.8 KiB
208 lines
3.8 KiB
//========= Copyright (c) 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; |
|
} |
|
|
|
|