|
|
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include <assert.h>
#include <ctype.h>
#include <vgui/MouseCode.h>
#include <vgui/KeyCode.h>
#include <KeyValues.h>
#include <vgui/ISurface.h>
#include <vgui/IVGui.h>
#include <vgui/IInput.h>
#include <vgui/IPanel.h>
#include <vgui/ILocalize.h>
#include <vgui_controls/Controls.h>
#include <vgui_controls/ScrollBar.h>
#include <vgui_controls/ImageList.h>
#include <vgui_controls/ImagePanel.h>
#include <vgui_controls/Label.h>
#include <vgui_controls/TextImage.h>
#include <vgui_controls/ListViewPanel.h>
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
using namespace vgui; enum { WINDOW_BORDER_WIDTH=2 // the width of the window's border
};
namespace vgui { class ListViewItem : public Label { DECLARE_CLASS_SIMPLE( ListViewItem, Label );
public: ListViewItem(Panel *parent) : Label(parent, NULL, "") { m_pListViewPanel = (ListViewPanel*) parent; m_pData = NULL; m_bSelected = false; SetPaintBackgroundEnabled(true); }
~ListViewItem() { if (m_pData) { m_pData->deleteThis(); m_pData = NULL; } }
void SetData(const KeyValues *data) { if (m_pData) { m_pData->deleteThis(); } m_pData = data->MakeCopy(); }
virtual void OnMousePressed( MouseCode code) { m_pListViewPanel->OnItemMousePressed(this, code); }
virtual void OnMouseDoublePressed( MouseCode code) { // double press should only select the item
m_pListViewPanel->OnItemMouseDoublePressed(this, code); }
KeyValues *GetData() { return m_pData; }
void SetSelected(bool bSelected) { if (bSelected == m_bSelected) return;
m_bSelected = bSelected; if (bSelected) { RequestFocus(); }
UpdateImage(); InvalidateLayout(); Repaint(); }
virtual void PerformLayout() { TextImage *textImage = GetTextImage(); if (m_bSelected) { VPANEL focus = input()->GetFocus(); // if one of the children of the SectionedListPanel has focus, then 'we have focus' if we're selected
if (HasFocus() || (focus && ipanel()->HasParent(focus, GetVParent()))) { textImage->SetColor(m_ArmedFgColor2); } else { textImage->SetColor(m_FgColor2); } } else { textImage->SetColor(GetFgColor()); } BaseClass::PerformLayout(); Repaint(); }
virtual void PaintBackground() { int wide, tall; GetSize(wide, tall);
if ( m_bSelected ) { VPANEL focus = input()->GetFocus(); // if one of the children of the SectionedListPanel has focus, then 'we have focus' if we're selected
if (HasFocus() || (focus && ipanel()->HasParent(focus, GetVParent()))) { surface()->DrawSetColor(m_ArmedBgColor); } else { surface()->DrawSetColor(m_SelectionBG2Color); } } else { surface()->DrawSetColor(GetBgColor()); } surface()->DrawFilledRect(0, 0, wide, tall); }
virtual void ApplySchemeSettings(IScheme *pScheme) { BaseClass::ApplySchemeSettings(pScheme);
m_ArmedFgColor2 = GetSchemeColor("ListPanel.SelectedTextColor", pScheme); m_ArmedBgColor = GetSchemeColor("ListPanel.SelectedBgColor", pScheme);
m_FgColor1 = GetSchemeColor("ListPanel.TextColor", pScheme); m_FgColor2 = GetSchemeColor("ListPanel.SelectedTextColor", pScheme);
m_BgColor = GetSchemeColor("ListPanel.BgColor", GetBgColor(), pScheme); m_BgColor = GetSchemeColor("ListPanel.TextBgColor", m_BgColor, pScheme); m_SelectionBG2Color = GetSchemeColor("ListPanel.SelectedOutOfFocusBgColor", pScheme); SetBgColor(m_BgColor); SetFgColor(m_FgColor1);
UpdateImage(); }
void UpdateImage() { if ( m_pListViewPanel->m_pImageList ) { int imageIndex = 0; if ( m_bSelected ) { imageIndex = m_pData->GetInt("imageSelected", 0); } if ( imageIndex == 0 ) { imageIndex = m_pData->GetInt("image", 0); } if ( m_pListViewPanel->m_pImageList->IsValidIndex(imageIndex) ) { SetImageAtIndex(0, m_pListViewPanel->m_pImageList->GetImage(imageIndex), 0); } else { // use the default
SetImageAtIndex(0, m_pListViewPanel->m_pImageList->GetImage(1), 0); } SizeToContents(); InvalidateLayout(); } }
private:
Color m_FgColor1; Color m_FgColor2; Color m_BgColor; Color m_ArmedFgColor2; Color m_ArmedBgColor; Color m_SelectionBG2Color;
//IBorder *_keyFocusBorder; // maybe in the future when I'm the 'active' but not selected item, I'll have a border
KeyValues *m_pData; ListViewPanel *m_pListViewPanel; bool m_bSelected; }; }
static bool DefaultSortFunc(KeyValues *kv1, KeyValues *kv2) { const char *string1 = kv1->GetString("text"); const char *string2 = kv2->GetString("text"); return Q_stricmp(string1, string2) < 0; }
DECLARE_BUILD_FACTORY( ListViewPanel );
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
ListViewPanel::ListViewPanel(Panel *parent, const char *panelName) : Panel(parent, panelName) { m_iRowHeight = 20; m_bNeedsSort = false; m_hFont = NULL; m_pImageList = NULL; m_bDeleteImageListWhenDone = false; m_pSortFunc = DefaultSortFunc; m_ShiftStartItemID = -1;
m_hbar = new ScrollBar(this, "HorizScrollBar", false); m_hbar->AddActionSignalTarget(this); m_hbar->SetVisible(false); }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
ListViewPanel::~ListViewPanel() { DeleteAllItems();
delete m_hbar;
if ( m_bDeleteImageListWhenDone ) { delete m_pImageList; m_pImageList = NULL; } }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
int ListViewPanel::AddItem(const KeyValues *data, bool bScrollToItem, bool bSortOnAdd) { ListViewItem *pNewItem = new ListViewItem(this); pNewItem->SetData(data); if (m_hFont) { pNewItem->SetFont(m_hFont); } int itemID = m_DataItems.AddToTail(pNewItem); ApplyItemChanges(itemID); m_SortedItems.AddToTail(itemID);
if ( bSortOnAdd ) { m_bNeedsSort = true; }
InvalidateLayout();
if ( bScrollToItem ) { ScrollToItem(itemID); }
return itemID; }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ListViewPanel::ScrollToItem(int itemID) { if (!m_hbar->IsVisible()) { return; } int val = m_hbar->GetValue();
int wide, tall; GetSize( wide, tall );
int maxWidth = GetItemsMaxWidth(); int maxColVisible = wide / maxWidth; int itemsPerCol = GetItemsPerColumn();
int itemIndex = m_SortedItems.Find(itemID); int desiredCol = itemIndex / itemsPerCol; if (desiredCol < val || desiredCol >= (val + maxColVisible) ) { m_hbar->SetValue(desiredCol); }
InvalidateLayout(); }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
int ListViewPanel::GetItemCount() { return m_DataItems.Count(); }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
KeyValues *ListViewPanel::GetItem(int itemID) { if ( !m_DataItems.IsValidIndex(itemID) ) return NULL;
return m_DataItems[itemID]->GetData(); }
//-----------------------------------------------------------------------------
// Purpose: Get ItemID from position in panel - valid from [0, GetItemCount)
//-----------------------------------------------------------------------------
int ListViewPanel::GetItemIDFromPos(int iPos) { if ( m_SortedItems.IsValidIndex(iPos) ) { return m_SortedItems[iPos]; } else { return m_DataItems.InvalidIndex(); } }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ListViewPanel::ApplyItemChanges(int itemID) { if ( !m_DataItems.IsValidIndex(itemID) ) return; KeyValues *kv = m_DataItems[itemID]->GetData(); ListViewItem *pLabel = m_DataItems[itemID];
pLabel->SetText(kv->GetString("text")); pLabel->SetTextImageIndex(1); pLabel->SetImagePreOffset(1, 5);
TextImage *pTextImage = pLabel->GetTextImage(); pTextImage->ResizeImageToContent();
pLabel->UpdateImage(); pLabel->SizeToContents(); pLabel->InvalidateLayout(); }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ListViewPanel::RemoveItem(int itemID) { if ( !m_DataItems.IsValidIndex(itemID) ) return;
m_DataItems[itemID]->MarkForDeletion();
// mark the keyValues for deletion
m_DataItems.Remove(itemID); m_SortedItems.FindAndRemove(itemID); m_SelectedItems.FindAndRemove(itemID);
InvalidateLayout(); }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ListViewPanel::DeleteAllItems() { FOR_EACH_LL( m_DataItems, index ) { m_DataItems[index]->MarkForDeletion(); } m_DataItems.RemoveAll(); m_SortedItems.RemoveAll(); m_SelectedItems.RemoveAll(); }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
int ListViewPanel::InvalidItemID() { return m_DataItems.InvalidIndex(); }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool ListViewPanel::IsValidItemID(int itemID) { return m_DataItems.IsValidIndex(itemID); }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ListViewPanel::SetSortFunc(ListViewSortFunc_t func) { if ( func ) { m_pSortFunc = func; SortList(); } }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ListViewPanel::SortList() { m_SortedItems.RemoveAll();
// find all the items in this section
for( int i = m_DataItems.Head(); i != m_DataItems.InvalidIndex(); i = m_DataItems.Next( i ) ) { // insert the items sorted
if (m_pSortFunc) { int insertionPoint; for (insertionPoint = 0; insertionPoint < m_SortedItems.Count(); insertionPoint++) { if ( m_pSortFunc(m_DataItems[i]->GetData(), m_DataItems[m_SortedItems[insertionPoint]]->GetData() ) ) break; } if (insertionPoint == m_SortedItems.Count()) { m_SortedItems.AddToTail(i); } else { m_SortedItems.InsertBefore(insertionPoint, i); } } else { // just add to the end
m_SortedItems.AddToTail(i); } } }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ListViewPanel::SetImageList(ImageList *imageList, bool deleteImageListWhenDone) { // get rid of existing list image if there's one and we're supposed to get rid of it
if ( m_pImageList && m_bDeleteImageListWhenDone ) { delete m_pImageList; m_pImageList = NULL; }
m_bDeleteImageListWhenDone = deleteImageListWhenDone; m_pImageList = imageList;
FOR_EACH_LL( m_DataItems, i ) { m_DataItems[i]->UpdateImage(); } }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ListViewPanel::SetFont(HFont font) { Assert( font ); if ( !font ) return;
m_hFont = font; m_iRowHeight = surface()->GetFontTall(font) + 1; FOR_EACH_LL( m_DataItems, i ) { m_DataItems[i]->SetFont(m_hFont); TextImage *pTextImage = m_DataItems[i]->GetTextImage(); pTextImage->ResizeImageToContent(); m_DataItems[i]->SizeToContents(); } } //-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
int ListViewPanel::GetSelectedItemsCount() { return m_SelectedItems.Count(); }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
int ListViewPanel::GetSelectedItem(int selectionIndex) { if ( m_SelectedItems.IsValidIndex(selectionIndex) ) return m_SelectedItems[selectionIndex];
return -1; }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ListViewPanel::ClearSelectedItems() { int i; for (i = 0 ; i < m_SelectedItems.Count(); i++) { if ( m_DataItems.IsValidIndex(m_SelectedItems[i]) ) { m_DataItems[m_SelectedItems[i]]->SetSelected(false); } } m_SelectedItems.RemoveAll(); }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ListViewPanel::AddSelectedItem(int itemID) { if ( m_SelectedItems.Find(itemID) == -1 ) { m_SelectedItems.AddToTail(itemID); m_DataItems[itemID]->SetSelected(true); m_LastSelectedItemID = itemID; m_ShiftStartItemID = itemID; PostActionSignal(new KeyValues("ListViewItemSelected")); } }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ListViewPanel::SetSingleSelectedItem(int itemID) { ClearSelectedItems(); AddSelectedItem(itemID); }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ListViewPanel::OnMouseWheeled(int delta) { int val = m_hbar->GetValue(); val -= delta; m_hbar->SetValue(val); }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ListViewPanel::OnSizeChanged(int wide, int tall) { BaseClass::OnSizeChanged(wide, tall); InvalidateLayout(); Repaint(); } //-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
int ListViewPanel::GetItemsMaxWidth() { int maxWidth = 0; FOR_EACH_LL( m_DataItems, i ) { int labelWide, labelTall; m_DataItems[i]->GetSize(labelWide, labelTall); if (labelWide > maxWidth) { maxWidth = labelWide + 25; } } return maxWidth; }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ListViewPanel::PerformLayout() { if (m_bNeedsSort) { SortList(); }
if ( m_DataItems.Count() == 0 ) return;
int wide, tall; GetSize(wide, tall);
int maxWidth = GetItemsMaxWidth(); if (maxWidth < 24) { maxWidth = 24; } int maxColVisible = wide / maxWidth;
m_hbar->SetVisible(false); int itemsPerCol = GetItemsPerColumn(); if (itemsPerCol < 1) { itemsPerCol = 1; } int cols = ( GetItemCount() + (itemsPerCol - 1) ) / itemsPerCol;
int startItem = 0; if ( cols > maxColVisible) { m_hbar->SetVisible(true);
// recalulate # per column now that we've made the hbar visible
itemsPerCol = GetItemsPerColumn(); cols = ( GetItemCount() + (itemsPerCol - 1) ) / (itemsPerCol > 0 ? itemsPerCol : 1 );
m_hbar->SetEnabled(false); m_hbar->SetRangeWindow( maxColVisible ); m_hbar->SetRange( 0, cols); m_hbar->SetButtonPressedScrollValue( 1 ); m_hbar->SetPos(0, tall - (m_hbar->GetTall()+WINDOW_BORDER_WIDTH)); m_hbar->SetSize(wide - (WINDOW_BORDER_WIDTH*2), m_hbar->GetTall()); m_hbar->InvalidateLayout();
int val = m_hbar->GetValue(); startItem += val*itemsPerCol; } else { m_hbar->SetVisible(false); } int lastItemVisible = startItem + (( maxColVisible + 1 )* itemsPerCol) - 1;
int itemsThisCol = 0; int x = 0; int y = 0; int i; for ( i = 0 ; i < m_SortedItems.Count() ; i++ ) { if ( i >= startItem && i <= lastItemVisible ) { m_DataItems[ m_SortedItems[i] ]->SetVisible(true); m_DataItems[ m_SortedItems[i] ]->SetPos(x, y); itemsThisCol++; if ( itemsThisCol == itemsPerCol ) { y = 0; x += maxWidth; itemsThisCol = 0; } else { y += m_iRowHeight; } } else { m_DataItems[ m_SortedItems[i] ]->SetVisible(false); } } } //-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ListViewPanel::Paint() { BaseClass::Paint(); }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ListViewPanel::ApplySchemeSettings(IScheme *pScheme) { BaseClass::ApplySchemeSettings(pScheme);
SetBgColor(GetSchemeColor("ListPanel.BgColor", pScheme)); SetBorder(pScheme->GetBorder("ButtonDepressedBorder"));
m_LabelFgColor = GetSchemeColor("ListPanel.TextColor", pScheme); m_SelectionFgColor = GetSchemeColor("ListPanel.SelectedTextColor", m_LabelFgColor, pScheme); m_hFont = pScheme->GetFont("Default", IsProportional()); SetFont(m_hFont); } //-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ListViewPanel::OnMousePressed( MouseCode code) { if (code == MOUSE_LEFT || code == MOUSE_RIGHT) { ClearSelectedItems(); RequestFocus(); } // check for context menu open
if (code == MOUSE_RIGHT) { // post it, but with the invalid row
PostActionSignal(new KeyValues("OpenContextMenu", "itemID", -1)); } }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ListViewPanel::OnShiftSelect(int itemID) { // if we dont' have a valid selected ItemID - then we just choose the first item
if ( !m_DataItems.IsValidIndex(m_ShiftStartItemID) ) { m_ShiftStartItemID = m_DataItems.Head(); }
// find out if the just pressed item is "earlier" or is the 'last selected item'
int lowerPos = -1, upperPos = -1; int i; for ( i = 0 ; i < m_SortedItems.Count() ; i++ ) { if ( m_SortedItems[i] == itemID ) { lowerPos = i; upperPos = m_SortedItems.Find(m_ShiftStartItemID); break; } else if ( m_SortedItems[i] == m_ShiftStartItemID ) { lowerPos = m_SortedItems.Find(m_ShiftStartItemID); upperPos = i; break; } } assert(lowerPos <= upperPos); if ( !input()->IsKeyDown(KEY_LCONTROL) && !input()->IsKeyDown(KEY_RCONTROL) ) { ClearSelectedItems(); }
for ( i = lowerPos ; i <= upperPos ; i ++) { // do not use AddSelectedItem because we don't want to switch the shiftStartItemID
m_DataItems[ m_SortedItems[i] ]->SetSelected(true); m_SelectedItems.AddToTail(m_SortedItems[i]); m_LastSelectedItemID = itemID; } }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ListViewPanel::OnItemMousePressed(ListViewItem* pItem, MouseCode code) { int itemID = m_DataItems.Find(pItem); if (!m_DataItems.IsValidIndex(itemID)) return; // check for context menu open
if (code == MOUSE_RIGHT) { // if this is a new item - unselect everything else
if ( m_SelectedItems.Find(itemID) == -1) { ClearSelectedItems(); AddSelectedItem(itemID); }
PostActionSignal(new KeyValues("OpenContextMenu", "itemID", itemID)); } else { if ( input()->IsKeyDown(KEY_LSHIFT) || input()->IsKeyDown(KEY_RSHIFT) ) { OnShiftSelect(itemID); } else if ( input()->IsKeyDown(KEY_LCONTROL) || input()->IsKeyDown(KEY_RCONTROL) ) { if ( m_SelectedItems.Find(itemID) != -1) { m_SelectedItems.FindAndRemove(itemID); pItem->SetSelected(false); // manually select these since we 'last' clicked on these items
m_ShiftStartItemID = itemID; m_LastSelectedItemID = itemID; m_DataItems[itemID]->RequestFocus(); } else { AddSelectedItem(itemID); } } else { ClearSelectedItems(); AddSelectedItem(itemID); } } }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ListViewPanel::OnMouseDoublePressed( MouseCode code) { }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ListViewPanel::OnItemMouseDoublePressed(ListViewItem* pItem, MouseCode code) { if (code == MOUSE_LEFT) { OnKeyCodeTyped(KEY_ENTER); } }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ListViewPanel::FinishKeyPress(int itemID) { if ( input()->IsKeyDown(KEY_LSHIFT) || input()->IsKeyDown(KEY_RSHIFT) ) { OnShiftSelect(itemID); } else if ( input()->IsKeyDown(KEY_LCONTROL) || input()->IsKeyDown(KEY_RCONTROL) ) { m_DataItems[itemID]->RequestFocus(); m_LastSelectedItemID = itemID; } else { SetSingleSelectedItem(itemID); } ScrollToItem(itemID); }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ListViewPanel::OnKeyCodeTyped( KeyCode code ) { if ( m_DataItems.Count() == 0 ) return;
switch (code) { case KEY_HOME: { if (m_SortedItems.Count() > 0) { int itemID = m_SortedItems[0]; FinishKeyPress(itemID); } break; } case KEY_END: { if (m_DataItems.Count() > 0) { int itemID = m_SortedItems[ m_SortedItems.Count() - 1 ]; FinishKeyPress(itemID); } break; }
case KEY_UP: { int itemPos = m_SortedItems.Find( m_LastSelectedItemID ); itemPos--; if (itemPos < 0) itemPos = 0;
FinishKeyPress(m_SortedItems[itemPos]); break; } case KEY_DOWN: { int itemPos = m_SortedItems.Find( m_LastSelectedItemID ); itemPos++; if (itemPos >= m_DataItems.Count()) itemPos = m_DataItems.Count() - 1;
FinishKeyPress(m_SortedItems[itemPos]); break; }
case KEY_LEFT: { int itemPos = m_SortedItems.Find( m_LastSelectedItemID ); itemPos -= GetItemsPerColumn(); if (itemPos < 0) { itemPos = 0; } FinishKeyPress(m_SortedItems[itemPos]); break; }
case KEY_RIGHT: { int itemPos = m_SortedItems.Find( m_LastSelectedItemID ); itemPos += GetItemsPerColumn(); if (itemPos >= m_SortedItems.Count()) { itemPos = m_SortedItems.Count() - 1; } FinishKeyPress(m_SortedItems[itemPos]); break; }
case KEY_PAGEUP: { int wide, tall; GetSize(wide, tall);
int maxWidth = GetItemsMaxWidth(); if (maxWidth == 0) { maxWidth = wide; } int maxColVisible = wide / maxWidth; int delta = maxColVisible * GetItemsPerColumn();
int itemPos = m_SortedItems.Find( m_LastSelectedItemID ); itemPos -= delta; if (itemPos < 0) { itemPos = 0; }
FinishKeyPress(m_SortedItems[itemPos]); break; } case KEY_PAGEDOWN: { int wide, tall; GetSize(wide, tall);
int maxWidth = GetItemsMaxWidth(); if (maxWidth == 0) { maxWidth = wide; } int maxColVisible = wide / maxWidth; int delta = maxColVisible * GetItemsPerColumn();
int itemPos = m_SortedItems.Find( m_LastSelectedItemID ); itemPos += delta; if (itemPos >= m_SortedItems.Count()) { itemPos = m_SortedItems.Count() - 1; }
FinishKeyPress(m_SortedItems[itemPos]); break; } default: { BaseClass::OnKeyCodeTyped(code); break; } } }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ListViewPanel::OnKeyTyped(wchar_t unichar) { if (!iswcntrl(unichar)) { wchar_t uniString[2]; uniString[0] = unichar; uniString[1] = 0;
char buf[2]; g_pVGuiLocalize->ConvertUnicodeToANSI(uniString, buf, sizeof(buf));
int i; int itemPos = m_SortedItems.Find(m_LastSelectedItemID); if ( m_SortedItems.IsValidIndex(itemPos)) { itemPos++; // start from the item AFTER our last selected Item and go to end
for ( i = itemPos ; i != m_SortedItems.Count(); i++) { KeyValues *kv = m_DataItems[ m_SortedItems[i] ]->GetData(); const char *pszText = kv->GetString("text"); if (!strnicmp(pszText, buf, 1)) { // select the next of this letter
SetSingleSelectedItem(m_SortedItems[i]); ScrollToItem(m_SortedItems[i]); return; } } // if the after this item we couldn't fine an item with the same letter, fall through and just start from the beginning of list to the last selected item
}
for ( i = 0 ; i < m_SortedItems.Count() ; i++ ) { // we've gone all the way around - break - if we had a valid index, this is one more that last selectedItem, if not it's an illegal index
if ( i == itemPos) break;
KeyValues *kv = m_DataItems[ m_SortedItems[i] ]->GetData(); const char *pszText = kv->GetString("text"); if (!strnicmp(pszText, buf, 1)) { SetSingleSelectedItem(m_SortedItems[i]); ScrollToItem(m_SortedItems[i]); return; } } } else BaseClass::OnKeyTyped(unichar); }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ListViewPanel::OnSliderMoved() { InvalidateLayout(); Repaint(); } //-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
int ListViewPanel::GetItemsPerColumn() { int wide, tall; GetSize(wide, tall);
if ( m_hbar->IsVisible() ) { tall -= m_hbar->GetTall(); }
return tall / m_iRowHeight; // should round down
}
|