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.
406 lines
10 KiB
406 lines
10 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
//============================================================================= |
|
|
|
#include "cbase.h" |
|
|
|
#include <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> |
|
#include "buypreset_listbox.h" |
|
|
|
// memdbgon must be the last include file in a .cpp file!!! |
|
#include <tier0/memdbgon.h> |
|
|
|
using namespace vgui; |
|
|
|
#ifndef max |
|
#define max(a,b) (((a) > (b)) ? (a) : (b)) |
|
#endif |
|
|
|
|
|
//-------------------------------------------------------------------------------------------------------------- |
|
//-------------------------------------------------------------------------------------------------------------- |
|
BuyPresetListBox::BuyPresetListBox( vgui::Panel *parent, char const *panelName ) : Panel( parent, panelName ) |
|
{ |
|
m_visibleIndex = 0; |
|
m_lastSize = 0; |
|
|
|
SetBounds( 0, 0, 100, 100 ); |
|
|
|
m_vbar = new ScrollBar(this, "PanelListPanelVScroll", true); |
|
m_vbar->SetBounds( 0, 0, 20, 20 ); |
|
m_vbar->SetVisible(true); |
|
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); |
|
|
|
if( IsProportional() ) |
|
{ |
|
int width, height; |
|
int sw,sh; |
|
surface()->GetProportionalBase( width, height ); |
|
GetHudSize(sw, sh); |
|
|
|
// resize scrollbar, etc |
|
m_iScrollbarSize = static_cast<int>( static_cast<float>( SCROLLBAR_SIZE )*( static_cast<float>( sw )/ static_cast<float>( width ))); |
|
m_iDefaultHeight = static_cast<int>( static_cast<float>( DEFAULT_HEIGHT )*( static_cast<float>( sw )/ static_cast<float>( width ))); |
|
m_iPanelBuffer = static_cast<int>( static_cast<float>( PANELBUFFER )*( static_cast<float>( sw )/ static_cast<float>( width ))); |
|
} |
|
else |
|
{ |
|
m_iScrollbarSize = SCROLLBAR_SIZE; |
|
m_iDefaultHeight = DEFAULT_HEIGHT; |
|
m_iPanelBuffer = PANELBUFFER; |
|
} |
|
} |
|
|
|
//-------------------------------------------------------------------------------------------------------------- |
|
BuyPresetListBox::~BuyPresetListBox() |
|
{ |
|
// free data from table |
|
DeleteAllItems(); |
|
} |
|
|
|
//-------------------------------------------------------------------------------------------------------------- |
|
/** |
|
* Passes commands up to the parent |
|
*/ |
|
void BuyPresetListBox::OnCommand( const char *command ) |
|
{ |
|
GetParent()->OnCommand( command ); |
|
} |
|
|
|
//-------------------------------------------------------------------------------------------------------------- |
|
/** |
|
* Scrolls the list according to the mouse wheel movement |
|
*/ |
|
void BuyPresetListBox::OnMouseWheeled(int delta) |
|
{ |
|
int scale = 3; |
|
if ( m_items.Count() ) |
|
{ |
|
Panel *panel = m_items[0].panel; |
|
if ( panel ) |
|
{ |
|
scale = panel->GetTall() + m_iPanelBuffer; |
|
} |
|
} |
|
int val = m_vbar->GetValue(); |
|
val -= (delta * scale); |
|
m_vbar->SetValue(val); |
|
} |
|
|
|
//-------------------------------------------------------------------------------------------------------------- |
|
/** |
|
* Computes vertical pixels needed by listbox contents |
|
*/ |
|
int BuyPresetListBox::computeVPixelsNeeded( void ) |
|
{ |
|
int pixels = 0; |
|
|
|
int i; |
|
for ( i = 0; i < m_items.Count(); i++ ) |
|
{ |
|
Panel *panel = m_items[i].panel; |
|
if ( !panel ) |
|
continue; |
|
|
|
int w, h; |
|
panel->GetSize( w, h ); |
|
|
|
pixels += m_iPanelBuffer; // add in buffer. between items. |
|
pixels += h; |
|
} |
|
|
|
pixels += m_iPanelBuffer; // add in buffer below last item |
|
|
|
return pixels; |
|
} |
|
|
|
//-------------------------------------------------------------------------------------------------------------- |
|
/** |
|
* Adds an item to the end of the listbox. UserData is assumed to be a pointer that can be freed by the listbox if non-NULL. |
|
*/ |
|
int BuyPresetListBox::AddItem( vgui::Panel *panel, IBuyPresetListBoxUserData * userData ) |
|
{ |
|
assert(panel); |
|
|
|
DataItem item = { panel, userData }; |
|
|
|
panel->SetParent( m_pPanelEmbedded ); |
|
|
|
m_items.AddToTail( item ); |
|
|
|
InvalidateLayout(); |
|
return m_items.Count(); |
|
} |
|
|
|
//-------------------------------------------------------------------------------------------------------------- |
|
/** |
|
* Exchanges two items in the listbox |
|
*/ |
|
void BuyPresetListBox::SwapItems( int index1, int index2 ) |
|
{ |
|
if ( index1 < 0 || index2 < 0 || index1 >= m_items.Count() || index2 >= m_items.Count() ) |
|
{ |
|
return; |
|
} |
|
|
|
DataItem temp = m_items[index1]; |
|
m_items[index1] = m_items[index2]; |
|
m_items[index2] = temp; |
|
|
|
InvalidateLayout(); |
|
} |
|
|
|
//-------------------------------------------------------------------------------------------------------------- |
|
/** |
|
* Returns the number of items in the listbox |
|
*/ |
|
int BuyPresetListBox::GetItemCount( void ) const |
|
{ |
|
return m_items.Count(); |
|
} |
|
|
|
//-------------------------------------------------------------------------------------------------------------- |
|
/** |
|
* Returns the panel in the given index, or NULL |
|
*/ |
|
Panel * BuyPresetListBox::GetItemPanel(int index) const |
|
{ |
|
if ( index < 0 || index >= m_items.Count() ) |
|
return NULL; |
|
|
|
return m_items[index].panel; |
|
} |
|
|
|
//-------------------------------------------------------------------------------------------------------------- |
|
/** |
|
* Returns the userData in the given index, or NULL |
|
*/ |
|
auto BuyPresetListBox::GetItemUserData(int index) -> IBuyPresetListBoxUserData * |
|
{ |
|
if ( index < 0 || index >= m_items.Count() ) |
|
{ |
|
return NULL; |
|
} |
|
|
|
return m_items[index].userData; |
|
} |
|
|
|
//-------------------------------------------------------------------------------------------------------------- |
|
/** |
|
* Sets the userData in the given index |
|
*/ |
|
void BuyPresetListBox::SetItemUserData( int index, IBuyPresetListBoxUserData * userData ) |
|
{ |
|
if ( index < 0 || index >= m_items.Count() ) |
|
return; |
|
|
|
m_items[index].userData = userData; |
|
} |
|
|
|
//-------------------------------------------------------------------------------------------------------------- |
|
/** |
|
* Removes an item from the table (changing the indices of all following items), deleting the panel and userData |
|
*/ |
|
void BuyPresetListBox::RemoveItem(int index) |
|
{ |
|
if ( index < 0 || index >= m_items.Count() ) |
|
return; |
|
|
|
DataItem item = m_items[index]; |
|
if ( item.panel ) |
|
{ |
|
item.panel->MarkForDeletion(); |
|
} |
|
if ( item.userData ) |
|
{ |
|
delete item.userData; |
|
} |
|
|
|
m_items.Remove( index ); |
|
|
|
InvalidateLayout(); |
|
} |
|
|
|
//-------------------------------------------------------------------------------------------------------------- |
|
/** |
|
* clears the listbox, deleting all panels and userData |
|
*/ |
|
void BuyPresetListBox::DeleteAllItems() |
|
{ |
|
while ( m_items.Count() ) |
|
{ |
|
RemoveItem( 0 ); |
|
} |
|
|
|
// move the scrollbar to the top of the list |
|
m_vbar->SetValue(0); |
|
InvalidateLayout(); |
|
} |
|
|
|
//-------------------------------------------------------------------------------------------------------------- |
|
/** |
|
* Handles Count changes |
|
*/ |
|
void BuyPresetListBox::OnSizeChanged(int wide, int tall) |
|
{ |
|
BaseClass::OnSizeChanged(wide, tall); |
|
InvalidateLayout(); |
|
} |
|
|
|
//-------------------------------------------------------------------------------------------------------------- |
|
/** |
|
* Positions listbox items, etc after internal changes |
|
*/ |
|
void BuyPresetListBox::PerformLayout() |
|
{ |
|
int wide, tall; |
|
GetSize( wide, tall ); |
|
|
|
int vpixels = computeVPixelsNeeded(); |
|
|
|
int visibleIndex = m_visibleIndex; |
|
|
|
//!! need to make it recalculate scroll positions |
|
m_vbar->SetVisible(true); |
|
m_vbar->SetEnabled(false); |
|
m_vbar->SetRange( 0, (MAX( 0, vpixels - tall + m_iDefaultHeight )) ); |
|
m_vbar->SetRangeWindow( m_iDefaultHeight ); |
|
m_vbar->SetButtonPressedScrollValue( m_iDefaultHeight ); // standard height of labels/buttons etc. |
|
m_vbar->SetPos(wide - m_iScrollbarSize, 1); |
|
m_vbar->SetSize(m_iScrollbarSize, tall - 2); |
|
|
|
m_visibleIndex = visibleIndex; |
|
|
|
int top = MAX( 0, m_vbar->GetValue() ); |
|
|
|
m_pPanelEmbedded->SetPos( 1, -top ); |
|
m_pPanelEmbedded->SetSize( wide-m_iScrollbarSize -2, vpixels ); |
|
|
|
// Now lay out the controls on the embedded panel |
|
int y = 0; |
|
int h = 0; |
|
int totalh = 0; |
|
|
|
int i; |
|
for ( i = 0; i < m_items.Count(); i++, y += h ) |
|
{ |
|
// add in a little buffer between panels |
|
y += m_iPanelBuffer; |
|
DataItem item = m_items[i]; |
|
|
|
h = item.panel->GetTall(); |
|
|
|
totalh += h; |
|
item.panel->SetBounds( 8, y, wide - m_iScrollbarSize - 8 - 8, h ); |
|
item.panel->InvalidateLayout(); |
|
} |
|
|
|
if ( m_visibleIndex >= 0 && m_visibleIndex < m_items.Count() ) |
|
{ |
|
|
|
int vpos = 0; |
|
|
|
int tempWide, tempTall; |
|
GetSize( tempWide, tempTall ); |
|
|
|
int vtop, vbottom; |
|
m_vbar->GetRange( vtop, vbottom ); |
|
|
|
int tempTop = MAX( 0, m_vbar->GetValue() ); // top pixel in the embedded panel |
|
int bottom = tempTop + tempTall - 2; |
|
|
|
int itemTop, itemLeft, itemBottom, itemRight; |
|
m_items[m_visibleIndex].panel->GetBounds( itemLeft, itemTop, itemRight, itemBottom ); |
|
itemBottom += itemTop; |
|
itemRight += itemLeft; |
|
|
|
if ( itemTop < tempTop ) |
|
{ |
|
// item's top is too high |
|
vpos -= ( tempTop - itemTop ); |
|
|
|
m_vbar->SetValue(vpos); |
|
OnSliderMoved(vpos); |
|
} |
|
else if ( itemBottom > bottom ) |
|
{ |
|
// item's bottom is too low |
|
vpos += ( itemBottom - bottom ); |
|
|
|
m_vbar->SetValue(vpos); |
|
OnSliderMoved(vpos); |
|
} |
|
} |
|
|
|
if ( m_lastSize == vpixels ) |
|
{ |
|
m_visibleIndex = -1; |
|
} |
|
m_lastSize = vpixels; |
|
} |
|
|
|
//-------------------------------------------------------------------------------------------------------------- |
|
/** |
|
* Try to ensure that the given index is visible |
|
*/ |
|
void BuyPresetListBox::MakeItemVisible( int index ) |
|
{ |
|
m_visibleIndex = index; |
|
m_lastSize = 0; |
|
} |
|
|
|
//-------------------------------------------------------------------------------------------------------------- |
|
/** |
|
* Loads colors, fonts, etc |
|
*/ |
|
void BuyPresetListBox::ApplySchemeSettings(IScheme *pScheme) |
|
{ |
|
BaseClass::ApplySchemeSettings(pScheme); |
|
|
|
SetBgColor(GetSchemeColor("BuyPresetListBox.BgColor", GetBgColor(), pScheme)); |
|
|
|
SetBorder(pScheme->GetBorder("BrowserBorder")); |
|
m_vbar->SetBorder(pScheme->GetBorder("BrowserBorder")); |
|
|
|
PerformLayout(); |
|
} |
|
|
|
|
|
//-------------------------------------------------------------------------------------------------------------- |
|
/** |
|
* Handles slider being dragged |
|
*/ |
|
void BuyPresetListBox::OnSliderMoved( int position ) |
|
{ |
|
InvalidateLayout(); |
|
Repaint(); |
|
} |
|
|
|
|
|
//-------------------------------------------------------------------------------------------------------------- |
|
/** |
|
* Moves slider to the top |
|
*/ |
|
void BuyPresetListBox::MoveScrollBarToTop() |
|
{ |
|
m_vbar->SetValue(0); |
|
OnSliderMoved(0); |
|
} |
|
|
|
|