1 Star 0 Fork 0

yoyojacky/CSMoE

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
SectionedListPanel.cpp 47.85 KB
一键复制 编辑 原始数据 按行查看 历史
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738
//========= Copyright ?1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include <stdio.h>
#include <vgui/IInput.h>
#include <vgui/IInputInternal.h>
#include <vgui/IPanel.h>
#include <vgui/ILocalize.h>
#include <vgui/IScheme.h>
#include <vgui/ISurface.h>
#include <vgui/MouseCode.h>
#include <tier1/KeyValues.h>
#include <tier1/utlvector.h>
#include "SectionedListPanel.h"
#include "Button.h"
#include "Controls.h"
#include "Label.h"
#include "ScrollBar.h"
#include "TextImage.h"
#include "ImageList.h"
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
using namespace vgui2;
enum
{
BUTTON_HEIGHT_DEFAULT = 20,
BUTTON_HEIGHT_SPACER = 7,
SECTION_GAP = 8,
COLUMN_DATA_INDENT = 6,
COLUMN_DATA_GAP = 2,
};
namespace vgui2
{
//-----------------------------------------------------------------------------
// Purpose: header label that separates and names each section
//-----------------------------------------------------------------------------
class CSectionHeader : public Label
{
DECLARE_CLASS_SIMPLE( CSectionHeader, Label );
public:
CSectionHeader(SectionedListPanel *parent, const char *name, int sectionID) : Label(parent, name, "")
{
m_pListPanel = parent;
m_iSectionID = sectionID;
SetTextImageIndex(-1);
ClearImages();
SetPaintBackgroundEnabled( false );
}
CSectionHeader(SectionedListPanel *parent, const wchar_t *name, int sectionID) : Label(parent, "SectionHeader", "")
{
SetText(name);
SetVisible(false);
m_pListPanel = parent;
m_iSectionID = sectionID;
SetTextImageIndex(-1);
ClearImages();
}
void ApplySchemeSettings(IScheme *pScheme)
{
BaseClass::ApplySchemeSettings(pScheme);
SetFgColor(GetSchemeColor("SectionedListPanel.HeaderTextColor", pScheme));
m_SectionDividerColor = GetSchemeColor("SectionedListPanel.DividerColor", pScheme);
SetBgColor(GetSchemeColor("SectionedListPanelHeader.BgColor", GetBgColor(), pScheme));
SetFont(pScheme->GetFont("DefaultVerySmall", IsProportional()));
ClearImages();
}
void Paint()
{
BaseClass::Paint();
int x, y, wide, tall;
GetBounds(x, y, wide, tall);
y = (tall - 2); // draw the line under the panel
surface()->DrawSetColor(m_SectionDividerColor);
surface()->DrawFilledRect(1, y, GetWide() - 2, y + 1);
}
void SetColor(Color col)
{
m_SectionDividerColor = col;
SetFgColor(col);
}
void PerformLayout()
{
BaseClass::PerformLayout();
// set up the text in the header
int colCount = m_pListPanel->GetColumnCountBySection(m_iSectionID);
if (colCount != GetImageCount())
{
// rebuild the image list
for (int i = 0; i < colCount; i++)
{
int columnFlags = m_pListPanel->GetColumnFlagsBySection(m_iSectionID, i);
IImage *image = NULL;
if (columnFlags & SectionedListPanel::HEADER_IMAGE)
{
//!! need some kind of image reference
image = NULL;
}
else
{
TextImage *textImage = new TextImage("");
textImage->SetFont(GetFont());
HFont fallback = m_pListPanel->GetColumnFallbackFontBySection( m_iSectionID, i );
if ( INVALID_FONT != fallback )
{
textImage->SetUseFallbackFont( true, fallback );
}
textImage->SetColor(GetFgColor());
image = textImage;
}
SetImageAtIndex(i, image, 0);
}
}
for (int repeat = 0; repeat <= 1; repeat++)
{
int xpos = 0;
for (int i = 0; i < colCount; i++)
{
int columnFlags = m_pListPanel->GetColumnFlagsBySection(m_iSectionID, i);
int columnWidth = m_pListPanel->GetColumnWidthBySection(m_iSectionID, i);
int maxWidth = columnWidth;
IImage *image = GetImageAtIndex(i);
if (!image)
{
xpos += columnWidth;
continue;
}
// set the image position within the label
int contentWide, wide, tall;
image->GetContentSize(wide, tall);
contentWide = wide;
// see if we can draw over the next few column headers (if we're left-aligned)
if (!(columnFlags & SectionedListPanel::COLUMN_RIGHT))
{
for (int j = i + 1; j < colCount; j++)
{
// see if this column header has anything for a header
int iwide = 0, itall = 0;
if (GetImageAtIndex(j))
{
GetImageAtIndex(j)->GetContentSize(iwide, itall);
}
if (iwide == 0)
{
// it's a blank header, ok to draw over it
maxWidth += m_pListPanel->GetColumnWidthBySection(m_iSectionID, j);
}
}
}
if (maxWidth >= 0)
{
wide = maxWidth;
}
if (columnFlags & SectionedListPanel::COLUMN_RIGHT)
{
SetImageBounds(i, xpos + wide - contentWide, contentWide - COLUMN_DATA_GAP);
}
else
{
SetImageBounds(i, xpos, wide - COLUMN_DATA_GAP);
}
xpos += columnWidth;
if (!(columnFlags & SectionedListPanel::HEADER_IMAGE))
{
Assert(dynamic_cast<TextImage *>(image) != NULL);
TextImage *textImage = (TextImage *)image;
textImage->SetText(m_pListPanel->GetColumnTextBySection(m_iSectionID, i));
textImage->ResizeImageToContentMaxWidth( maxWidth );
}
}
}
}
private:
int m_iSectionID;
Color m_SectionDividerColor;
SectionedListPanel *m_pListPanel;
};
//-----------------------------------------------------------------------------
// Purpose: Individual items in the list
//-----------------------------------------------------------------------------
class CItemButton : public Label
{
DECLARE_CLASS_SIMPLE( CItemButton, Label );
public:
CItemButton(SectionedListPanel *parent, int itemID) : Label(parent, NULL, "< item >")
{
m_pListPanel = parent;
m_iID = itemID;
m_pData = NULL;
Clear();
}
~CItemButton()
{
// free all the keyvalues
if (m_pData)
{
m_pData->deleteThis();
}
// clear any section data
SetSectionID(-1);
}
void Clear()
{
m_bSelected = false;
m_bOverrideColors = false;
m_iSectionID = -1;
SetPaintBackgroundEnabled( false );
SetTextImageIndex(-1);
ClearImages();
}
int GetID()
{
return m_iID;
}
void SetID(int itemID)
{
m_iID = itemID;
}
int GetSectionID()
{
return m_iSectionID;
}
void SetSectionID(int sectionID)
{
if (sectionID != m_iSectionID)
{
// free any existing textimage list
ClearImages();
// delete any images we've created
for (int i = 0; i < m_TextImages.Count(); i++)
{
delete m_TextImages[i];
}
m_TextImages.RemoveAll();
// mark the list as needing rebuilding
InvalidateLayout();
}
m_iSectionID = sectionID;
}
void SetData(const KeyValues *data)
{
if (m_pData)
{
m_pData->deleteThis();
}
m_pData = data->MakeCopy();
InvalidateLayout();
}
KeyValues *GetData()
{
return m_pData;
}
virtual void PerformLayout()
{
// get our button text
int colCount = m_pListPanel->GetColumnCountBySection(m_iSectionID);
if (!m_pData || colCount < 1)
{
SetText("< unset >");
}
else
{
if (colCount != GetImageCount())
{
// rebuild the image list
for (int i = 0; i < colCount; i++)
{
int columnFlags = m_pListPanel->GetColumnFlagsBySection(m_iSectionID, i);
if (!(columnFlags & SectionedListPanel::COLUMN_IMAGE))
{
TextImage *image = new TextImage("");
m_TextImages.AddToTail(image);
image->SetFont( GetFont() );
HFont fallback = m_pListPanel->GetColumnFallbackFontBySection( m_iSectionID, i );
if ( INVALID_FONT != fallback )
{
image->SetUseFallbackFont( true, fallback );
}
SetImageAtIndex(i, image, 0);
}
}
{for ( int i = GetImageCount(); i < colCount; i++ ) // make sure we have enough image slots
{
AddImage( NULL, 0 );
}}
}
// set the text for each column
int xpos = 0;
for (int i = 0; i < colCount; i++)
{
const char *keyname = m_pListPanel->GetColumnNameBySection(m_iSectionID, i);
int columnFlags = m_pListPanel->GetColumnFlagsBySection(m_iSectionID, i);
int maxWidth = m_pListPanel->GetColumnWidthBySection(m_iSectionID, i);
IImage *image = NULL;
if (columnFlags & SectionedListPanel::COLUMN_IMAGE)
{
// lookup which image is being referred to
if (m_pListPanel->m_pImageList)
{
int imageIndex = m_pData->GetInt(keyname, 0);
if (m_pListPanel->m_pImageList->IsValidIndex(imageIndex))
{
// 0 is always the blank image
if (imageIndex > 0)
{
image = m_pListPanel->m_pImageList->GetImage(imageIndex);
SetImageAtIndex(i, image, 0);
}
}
else
{
// this is mildly valid (CGamesList hits it because of the way it uses the image indices)
// Assert(!("Image index out of range for ImageList in SectionedListPanel"));
}
}
else
{
Assert(!("Images columns used in SectionedListPanel with no ImageList set"));
}
}
else
{
TextImage *textImage = dynamic_cast<TextImage *>(GetImageAtIndex(i));
if (textImage)
{
textImage->SetText(m_pData->GetString(keyname, ""));
textImage->ResizeImageToContentMaxWidth( maxWidth );
// set the text color based on the selection state - if one of the children of the SectionedListPanel has focus, then 'we have focus' if we're selected
VPANEL focus = input()->GetFocus();
if ( !m_bOverrideColors )
{
if (IsSelected() && !m_pListPanel->IsInEditMode())
{
if (HasFocus() || (focus && ipanel()->HasParent(focus, GetVParent())))
{
textImage->SetColor(m_ArmedFgColor2);
}
else
{
textImage->SetColor(m_OutOfFocusSelectedTextColor);
}
}
else if (columnFlags & SectionedListPanel::COLUMN_BRIGHT)
{
textImage->SetColor(m_ArmedFgColor1);
}
else
{
textImage->SetColor(m_FgColor2);
}
}
else
{
// custom colors
if (IsSelected() && (HasFocus() || (focus && ipanel()->HasParent(focus, GetVParent()))))
{
textImage->SetColor(m_ArmedFgColor2);
}
else
{
textImage->SetColor(GetFgColor());
}
}
}
image = textImage;
}
// set the image position within the label
int imageWide = 0, tall = 0;
int wide;
if (image)
{
image->GetContentSize(imageWide, tall);
}
if (maxWidth >= 0)
{
wide = maxWidth;
}
else
{
wide = imageWide;
}
if (i == 0 && !(columnFlags & SectionedListPanel::COLUMN_IMAGE))
{
// first column has an extra indent
SetImageBounds(i, xpos + COLUMN_DATA_INDENT, wide - (COLUMN_DATA_INDENT + COLUMN_DATA_GAP));
}
else
{
if (columnFlags & SectionedListPanel::COLUMN_CENTER)
{
int offSet = (wide / 2) - (imageWide / 2);
SetImageBounds(i, xpos + offSet, wide - offSet - COLUMN_DATA_GAP);
}
else if (columnFlags & SectionedListPanel::COLUMN_RIGHT)
{
SetImageBounds(i, xpos + wide - imageWide, wide - COLUMN_DATA_GAP);
}
else
{
SetImageBounds(i, xpos, wide - COLUMN_DATA_GAP);
}
}
xpos += wide;
}
}
BaseClass::PerformLayout();
}
virtual void ApplySchemeSettings(IScheme *pScheme)
{
BaseClass::ApplySchemeSettings(pScheme);
m_ArmedFgColor1 = GetSchemeColor("SectionedListPanel.BrightTextColor", pScheme);
m_ArmedFgColor2 = GetSchemeColor("SectionedListPanel.SelectedTextColor", pScheme);
m_OutOfFocusSelectedTextColor = GetSchemeColor("SectionedListPanel.OutOfFocusSelectedTextColor", pScheme);
m_ArmedBgColor = GetSchemeColor("SectionedListPanel.SelectedBgColor", pScheme);
m_FgColor2 = GetSchemeColor("SectionedListPanel.TextColor", pScheme);
m_BgColor = GetSchemeColor("SectionedListPanel.BgColor", GetBgColor(), pScheme);
m_SelectionBG2Color = GetSchemeColor("SectionedListPanel.OutOfFocusSelectedBgColor", pScheme);
ClearImages();
}
virtual void PaintBackground()
{
int wide, tall;
GetSize(wide, tall);
if (IsSelected() && !m_pListPanel->IsInEditMode())
{
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 OnMousePressed(MouseCode code)
{
if (code == MOUSE_LEFT)
{
m_pListPanel->PostActionSignal(new KeyValues("ItemLeftClick", "itemID", m_iID));
}
if (code == MOUSE_RIGHT)
{
KeyValues *msg = new KeyValues("ItemContextMenu", "itemID", m_iID);
msg->SetPtr("SubPanel", this);
m_pListPanel->PostActionSignal(msg);
}
m_pListPanel->SetSelectedItem(this);
}
void SetSelected(bool state)
{
if (m_bSelected != state)
{
if (state)
{
RequestFocus();
}
m_bSelected = state;
SetPaintBackgroundEnabled( state );
InvalidateLayout();
Repaint();
}
}
bool IsSelected()
{
return m_bSelected;
}
virtual void OnSetFocus()
{
InvalidateLayout(); // force the layout to be redone so we can change text color according to focus
BaseClass::OnSetFocus();
}
virtual void OnKillFocus()
{
InvalidateLayout(); // force the layout to be redone so we can change text color according to focus
BaseClass::OnSetFocus();
}
virtual void OnMouseDoublePressed(MouseCode code)
{
if (code == MOUSE_LEFT)
{
m_pListPanel->PostActionSignal(new KeyValues("ItemDoubleLeftClick", "itemID", m_iID));
// post up an enter key being hit
m_pListPanel->OnKeyCodeTyped(KEY_ENTER);
}
else
{
OnMousePressed(code);
}
m_pListPanel->SetSelectedItem(this);
}
void GetCellBounds(int column, int &xpos, int &columnWide)
{
xpos = 0, columnWide = 0;
int colCount = m_pListPanel->GetColumnCountBySection(m_iSectionID);
for (int i = 0; i < colCount; i++)
{
int maxWidth = m_pListPanel->GetColumnWidthBySection(m_iSectionID, i);
IImage *image = GetImageAtIndex(i);
if (!image)
continue;
// set the image position within the label
int wide, tall;
image->GetContentSize(wide, tall);
if (maxWidth >= 0)
{
wide = maxWidth;
}
if (i == column)
{
// found the cell size, bail
columnWide = wide;
return;
}
xpos += wide;
}
}
virtual void SetOverrideColors( bool state )
{
m_bOverrideColors = state;
}
private:
SectionedListPanel *m_pListPanel;
int m_iID;
int m_iSectionID;
KeyValues *m_pData;
Color m_FgColor2;
Color m_BgColor;
Color m_ArmedFgColor1;
Color m_ArmedFgColor2;
Color m_OutOfFocusSelectedTextColor;
Color m_ArmedBgColor;
Color m_SelectionBG2Color;
CUtlVector<vgui2::TextImage *> m_TextImages;
bool m_bSelected;
bool m_bOverrideColors;
};
}; // namespace vgui
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
SectionedListPanel::SectionedListPanel(vgui2::Panel *parent, const char *name) : BaseClass(parent, name)
{
m_pScrollBar = new ScrollBar(this, "SectionedScrollBar", true);
m_pScrollBar->SetVisible(false);
m_pScrollBar->AddActionSignalTarget(this);
m_iEditModeItemID = 0;
m_iEditModeColumn = 0;
m_bSortNeeded = false;
m_bVerticalScrollbarEnabled = true;
m_iLineSpacing = 20;
m_pImageList = NULL;
m_bDeleteImageListWhenDone = false;
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
SectionedListPanel::~SectionedListPanel()
{
}
//-----------------------------------------------------------------------------
// Purpose: Sorts the list
//-----------------------------------------------------------------------------
void SectionedListPanel::ReSortList()
{
m_SortedItems.RemoveAll();
int sectionStart = 0;
// layout the buttons
for (int sectionIndex = 0; sectionIndex < m_Sections.Size(); sectionIndex++)
{
section_t &section = m_Sections[sectionIndex];
sectionStart = m_SortedItems.Count();
// find all the items in this section
for( int i = m_Items.Head(); i != m_Items.InvalidIndex(); i = m_Items.Next( i ) )
{
if (m_Items[i]->GetSectionID() == m_Sections[sectionIndex].m_iID)
{
// insert the items sorted
if (section.m_pSortFunc)
{
int insertionPoint = sectionStart;
for (;insertionPoint < m_SortedItems.Count(); insertionPoint++)
{
if (section.m_pSortFunc(this, i, m_SortedItems[insertionPoint]->GetID()))
break;
}
if (insertionPoint == m_SortedItems.Count())
{
m_SortedItems.AddToTail(m_Items[i]);
}
else
{
m_SortedItems.InsertBefore(insertionPoint, m_Items[i]);
}
}
else
{
// just add to the end
m_SortedItems.AddToTail(m_Items[i]);
}
}
}
}
}
//-----------------------------------------------------------------------------
// Purpose: iterates through and sets up the position of all the sections and items
//-----------------------------------------------------------------------------
void SectionedListPanel::PerformLayout()
{
// lazy resort the list
if (m_bSortNeeded)
{
ReSortList();
m_bSortNeeded = false;
}
BaseClass::PerformLayout();
LayoutPanels(m_iContentHeight);
int cx, cy, cwide, ctall;
GetBounds(cx, cy, cwide, ctall);
if (m_iContentHeight > ctall && m_bVerticalScrollbarEnabled)
{
m_pScrollBar->SetVisible(true);
m_pScrollBar->MoveToFront();
m_pScrollBar->SetPos(cwide - m_pScrollBar->GetWide() - 2, 0);
m_pScrollBar->SetSize(m_pScrollBar->GetWide(), ctall - 2);
m_pScrollBar->SetRangeWindow(ctall);
m_pScrollBar->SetRange(0, m_iContentHeight);
m_pScrollBar->InvalidateLayout();
m_pScrollBar->Repaint();
// since we're just about to make the scrollbar visible, we need to re-layout
// the buttons since they depend on the scrollbar size
LayoutPanels(m_iContentHeight);
}
else
{
m_pScrollBar->SetValue(0);
m_pScrollBar->SetVisible(false);
}
}
//-----------------------------------------------------------------------------
// Purpose: lays out the sections and rows in the panel
//-----------------------------------------------------------------------------
void SectionedListPanel::LayoutPanels(int &contentTall)
{
int tall = GetSectionTall();
int x = 5, wide = GetWide() - 10;
int y = 5;
if (m_pScrollBar->IsVisible())
{
y -= m_pScrollBar->GetValue();
wide -= m_pScrollBar->GetWide();
}
int iStart = -1;
int iEnd = -1;
// layout the buttons
for (int sectionIndex = 0; sectionIndex < m_Sections.Size(); sectionIndex++)
{
section_t &section = m_Sections[sectionIndex];
iStart = -1;
iEnd = -1;
for (int i = 0; i < m_SortedItems.Count(); i++)
{
if (m_SortedItems[i]->GetSectionID() == m_Sections[sectionIndex].m_iID)
{
if (iStart == -1)
iStart = i;
iEnd = i;
}
}
// don't draw this section at all if their are no item in it
if (iStart == -1 && !section.m_bAlwaysVisible)
{
section.m_pHeader->SetVisible(false);
continue;
}
// draw the header
section.m_pHeader->SetBounds(x, y, wide, tall);
section.m_pHeader->SetVisible(true);
y += tall;
if (iStart == -1 && section.m_bAlwaysVisible)
{
}
else
{
// arrange all the items in this section underneath
for (int i = iStart; i <= iEnd; i++)
{
CItemButton *item = m_SortedItems[i]; //items[i];
item->SetBounds(x, y, wide, m_iLineSpacing);
// setup edit mode
if (m_hEditModePanel.Get() && m_iEditModeItemID == item->GetID())
{
int cx, cwide;
item->GetCellBounds(1, cx, cwide);
m_hEditModePanel->SetBounds(cx, y, cwide, tall);
}
y += m_iLineSpacing;
}
}
// add in a little boundry at the bottom
y += SECTION_GAP;
}
// calculate height
contentTall = y;
if (m_pScrollBar->IsVisible())
{
contentTall += m_pScrollBar->GetValue();
}
}
//-----------------------------------------------------------------------------
// Purpose: Ensures that the specified item is visible in the display
//-----------------------------------------------------------------------------
void SectionedListPanel::ScrollToItem(int iItem)
{
int tall = GetSectionTall();
int itemX, itemY ;
int nCurrentValue = m_pScrollBar->GetValue();
// find out where the item is
m_Items[iItem]->GetPos(itemX, itemY);
// add in the current scrollbar position
itemY += nCurrentValue;
// compare that in the list
int cx, cy, cwide, ctall;
GetBounds(cx, cy, cwide, ctall);
if (m_iContentHeight > ctall)
{
if (itemY < nCurrentValue)
{
// scroll up
m_pScrollBar->SetValue(itemY);
}
else if (itemY > nCurrentValue + ctall - tall)
{
// scroll down
m_pScrollBar->SetValue(itemY - ctall + tall);
}
else
{
// keep the current value
}
}
else
{
// area isn't big enough, just remove the scrollbar
m_pScrollBar->SetValue(0);
}
// reset scrollbar
Repaint();
}
//-----------------------------------------------------------------------------
// Purpose: sets background color & border
//-----------------------------------------------------------------------------
void SectionedListPanel::ApplySchemeSettings(IScheme *pScheme)
{
BaseClass::ApplySchemeSettings(pScheme);
SetBgColor(GetSchemeColor("SectionedListPanel.BgColor", GetBgColor(), pScheme));
SetBorder(pScheme->GetBorder("ButtonDepressedBorder"));
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void SectionedListPanel::ApplySettings(KeyValues *inResourceData)
{
BaseClass::ApplySettings(inResourceData);
m_iLineSpacing = inResourceData->GetInt("linespacing", 0);
if (!m_iLineSpacing)
{
m_iLineSpacing = 20;
}
if (IsProportional())
{
m_iLineSpacing = scheme()->GetProportionalScaledValueEx(GetScheme(), m_iLineSpacing);
}
}
//-----------------------------------------------------------------------------
// Purpose: passes on proportional state to children
//-----------------------------------------------------------------------------
void SectionedListPanel::SetProportional(bool state)
{
BaseClass::SetProportional(state);
// now setup the section headers and items
int i;
for (i = 0; i < m_Sections.Count(); i++)
{
m_Sections[i].m_pHeader->SetProportional(state);
}
FOR_EACH_LL( m_Items, j )
{
m_Items[j]->SetProportional(state);
}
}
//-----------------------------------------------------------------------------
// Purpose: sets whether or not the vertical scrollbar should ever be displayed
//-----------------------------------------------------------------------------
void SectionedListPanel::SetVerticalScrollbar(bool state)
{
m_bVerticalScrollbarEnabled = state;
}
//-----------------------------------------------------------------------------
// Purpose: adds a new section
//-----------------------------------------------------------------------------
void SectionedListPanel::AddSection(int sectionID, const char *name, SectionSortFunc_t sortFunc)
{
CSectionHeader *header = SETUP_PANEL(new CSectionHeader(this, name, sectionID));
AddSectionHelper(sectionID, header, sortFunc);
}
//-----------------------------------------------------------------------------
// Purpose: adds a new section
//-----------------------------------------------------------------------------
void SectionedListPanel::AddSection(int sectionID, const wchar_t *name, SectionSortFunc_t sortFunc)
{
CSectionHeader *header = SETUP_PANEL(new CSectionHeader(this, name, sectionID));
AddSectionHelper(sectionID, header, sortFunc);
}
//-----------------------------------------------------------------------------
// Purpose: helper function for AddSection
//-----------------------------------------------------------------------------
void SectionedListPanel::AddSectionHelper(int sectionID, CSectionHeader *header, SectionSortFunc_t sortFunc)
{
int index = m_Sections.AddToTail();
m_Sections[index].m_iID = sectionID;
m_Sections[index].m_pHeader = header;
m_Sections[index].m_pSortFunc = sortFunc;
m_Sections[index].m_bAlwaysVisible = false;
}
//-----------------------------------------------------------------------------
// Purpose: removes all the sections from the current panel
//-----------------------------------------------------------------------------
void SectionedListPanel::RemoveAllSections()
{
for (int i = 0; i < m_Sections.Count(); i++)
{
if (!m_Sections.IsValidIndex(i))
continue;
m_Sections[i].m_pHeader->SetVisible(false);
m_Sections[i].m_pHeader->MarkForDeletion();
}
m_Sections.RemoveAll();
m_Sections.Purge();
m_SortedItems.RemoveAll();
InvalidateLayout();
ReSortList();
}
//-----------------------------------------------------------------------------
// Purpose: adds a new column to a section
//-----------------------------------------------------------------------------
bool SectionedListPanel::AddColumnToSection(int sectionID, const char *columnName, const char *columnText, int columnFlags, int width, HFont fallbackFont /*= INVALID_FONT*/ )
{
wchar_t wtext[64];
wchar_t *pwtext = localize()->Find(columnText);
if (!pwtext)
{
localize()->ConvertANSIToUnicode(columnText, wtext, sizeof(wtext));
pwtext = wtext;
}
return AddColumnToSection(sectionID, columnName, pwtext, columnFlags, width, fallbackFont );
}
//-----------------------------------------------------------------------------
// Purpose: as above but with wchar_t's
//-----------------------------------------------------------------------------
bool SectionedListPanel::AddColumnToSection(int sectionID, const char *columnName, const wchar_t *columnText, int columnFlags, int width, HFont fallbackFont /*= INVALID_FONT*/ )
{
int index = FindSectionIndexByID(sectionID);
if (index < 0)
return false;
section_t &section = m_Sections[index];
// add the new column to the sections' list
index = section.m_Columns.AddToTail();
column_t &column = section.m_Columns[index];
Q_strncpy(column.m_szColumnName, columnName, sizeof(column.m_szColumnName));
wcsncpy(column.m_szColumnText, columnText, sizeof(column.m_szColumnText) / sizeof(wchar_t));
column.m_szColumnText[sizeof(column.m_szColumnText) / sizeof(wchar_t) - 1] = 0;
column.m_iColumnFlags = columnFlags;
column.m_iWidth = width;
column.m_hFallbackFont = fallbackFont;
return true;
}
//-----------------------------------------------------------------------------
// Purpose: modifies the text in an existing column
//-----------------------------------------------------------------------------
bool SectionedListPanel::ModifyColumn(int sectionID, const char *columnName, const wchar_t *columnText)
{
int index = FindSectionIndexByID(sectionID);
if (index < 0)
return false;
section_t &section = m_Sections[index];
// find the specified column
int columnIndex;
for (columnIndex = 0; columnIndex < section.m_Columns.Count(); columnIndex++)
{
if (!stricmp(section.m_Columns[columnIndex].m_szColumnName, columnName))
break;
}
if (!section.m_Columns.IsValidIndex(columnIndex))
return false;
column_t &column = section.m_Columns[columnIndex];
// modify the text
wcsncpy(column.m_szColumnText, columnText, sizeof(column.m_szColumnText) / sizeof(wchar_t));
column.m_szColumnText[sizeof(column.m_szColumnText) / sizeof(wchar_t) - 1] = 0;
section.m_pHeader->InvalidateLayout();
return true;
}
//-----------------------------------------------------------------------------
// Purpose: adds an item to the list; returns itemID
//-----------------------------------------------------------------------------
int SectionedListPanel::AddItem(int sectionID, const KeyValues *data)
{
int itemID = GetNewItemButton();
ModifyItem(itemID, sectionID, data);
// not sorted but in list
m_SortedItems.AddToTail(m_Items[itemID]);
m_bSortNeeded = true;
return itemID;
}
//-----------------------------------------------------------------------------
// Purpose: modifies an existing item; returns false if the item does not exist
//-----------------------------------------------------------------------------
bool SectionedListPanel::ModifyItem(int itemID, int sectionID, const KeyValues *data)
{
if ( !m_Items.IsValidIndex(itemID) )
return false;
InvalidateLayout();
m_Items[itemID]->SetSectionID(sectionID);
m_Items[itemID]->SetData(data);
m_Items[itemID]->InvalidateLayout();
m_bSortNeeded = true;
return true;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void SectionedListPanel::SetItemFgColor( int itemID, Color color )
{
Assert( m_Items.IsValidIndex(itemID) );
if ( !m_Items.IsValidIndex(itemID) )
return;
m_Items[itemID]->SetFgColor( color );
m_Items[itemID]->SetOverrideColors( true );
m_Items[itemID]->InvalidateLayout();
}
//-----------------------------------------------------------------------------
// Purpose: sets the color of a section text & underline
//-----------------------------------------------------------------------------
void SectionedListPanel::SetSectionFgColor(int sectionID, Color color)
{
if (!m_Sections.IsValidIndex(sectionID))
return;
m_Sections[sectionID].m_pHeader->SetColor(color);
}
//-----------------------------------------------------------------------------
// Purpose: forces a section to always be visible
//-----------------------------------------------------------------------------
void SectionedListPanel::SetSectionAlwaysVisible(int sectionID, bool visible)
{
if (!m_Sections.IsValidIndex(sectionID))
return;
m_Sections[sectionID].m_bAlwaysVisible = visible;
}
//-----------------------------------------------------------------------------
// Purpose: removes an item from the list; returns false if the item does not exist or is already removed
//-----------------------------------------------------------------------------
bool SectionedListPanel::RemoveItem(int itemID)
{
if ( !m_Items.IsValidIndex(itemID) )
return false;
m_SortedItems.FindAndRemove(m_Items[itemID]);
m_bSortNeeded = true;
m_Items[itemID]->MarkForDeletion();
m_Items.Remove(itemID);
InvalidateLayout();
return true;
}
//-----------------------------------------------------------------------------
// Purpose: returns the number of columns in a section
//-----------------------------------------------------------------------------
int SectionedListPanel::GetColumnCountBySection(int sectionID)
{
int index = FindSectionIndexByID(sectionID);
if (index < 0)
return NULL;
return m_Sections[index].m_Columns.Size();
}
//-----------------------------------------------------------------------------
// Purpose: returns the name of a column by section and column index; returns NULL if there are no more columns
// valid range of columnIndex is [0, GetColumnCountBySection)
//-----------------------------------------------------------------------------
const char *SectionedListPanel::GetColumnNameBySection(int sectionID, int columnIndex)
{
int index = FindSectionIndexByID(sectionID);
if (index < 0 || columnIndex >= m_Sections[index].m_Columns.Size())
return NULL;
return m_Sections[index].m_Columns[columnIndex].m_szColumnName;
}
//-----------------------------------------------------------------------------
// Purpose: returns the text for a column by section and column index
//-----------------------------------------------------------------------------
const wchar_t *SectionedListPanel::GetColumnTextBySection(int sectionID, int columnIndex)
{
int index = FindSectionIndexByID(sectionID);
if (index < 0 || columnIndex >= m_Sections[index].m_Columns.Size())
return NULL;
return m_Sections[index].m_Columns[columnIndex].m_szColumnText;
}
//-----------------------------------------------------------------------------
// Purpose: returns the type of a column by section and column index
//-----------------------------------------------------------------------------
int SectionedListPanel::GetColumnFlagsBySection(int sectionID, int columnIndex)
{
int index = FindSectionIndexByID(sectionID);
if (index < 0)
return 0;
if (columnIndex >= m_Sections[index].m_Columns.Size())
return 0;
return m_Sections[index].m_Columns[columnIndex].m_iColumnFlags;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
int SectionedListPanel::GetColumnWidthBySection(int sectionID, int columnIndex)
{
int index = FindSectionIndexByID(sectionID);
if (index < 0)
return 0;
if (columnIndex >= m_Sections[index].m_Columns.Size())
return 0;
return m_Sections[index].m_Columns[columnIndex].m_iWidth;
}
//-----------------------------------------------------------------------------
// Purpose: returns -1 if section not found
//-----------------------------------------------------------------------------
int SectionedListPanel::FindSectionIndexByID(int sectionID)
{
for (int i = 0; i < m_Sections.Size(); i++)
{
if (m_Sections[i].m_iID == sectionID)
{
return i;
}
}
return -1;
}
//-----------------------------------------------------------------------------
// Purpose: Called when the scrollbar is moved
//-----------------------------------------------------------------------------
void SectionedListPanel::OnSliderMoved()
{
InvalidateLayout();
Repaint();
}
//-----------------------------------------------------------------------------
// Purpose: Scrolls the list according to the mouse wheel movement
//-----------------------------------------------------------------------------
void SectionedListPanel::OnMouseWheeled(int delta)
{
if (m_hEditModePanel.Get())
{
// ignore mouse wheel in edit mode, forward right up to parent
CallParentFunction(new KeyValues("MouseWheeled", "delta", delta));
return;
}
// scroll the window based on the delta
int val = m_pScrollBar->GetValue();
val -= (delta * BUTTON_HEIGHT_DEFAULT * 3);
m_pScrollBar->SetValue(val);
}
//-----------------------------------------------------------------------------
// Purpose: Resets the scrollbar position on size change
//-----------------------------------------------------------------------------
void SectionedListPanel::OnSizeChanged(int wide, int tall)
{
BaseClass::OnSizeChanged(wide, tall);
m_pScrollBar->SetValue(0);
InvalidateLayout();
Repaint();
}
//-----------------------------------------------------------------------------
// Purpose: deselects any items
//-----------------------------------------------------------------------------
void SectionedListPanel::OnMousePressed(MouseCode code)
{
ClearSelection();
}
//-----------------------------------------------------------------------------
// Purpose: deselects any items
//-----------------------------------------------------------------------------
void SectionedListPanel::ClearSelection( void )
{
SetSelectedItem((CItemButton *)NULL);
}
void SectionedListPanel::MoveSelectionDown( void )
{
int itemID = GetSelectedItem();
Assert(itemID != -1);
if (!m_SortedItems.Count()) // if the list has been emptied
return;
int i;
for (i = 0; i < m_SortedItems.Count(); i++)
{
if (m_SortedItems[i]->GetID() == itemID)
break;
}
Assert(i != m_SortedItems.Count());
// we're already on the end
if (i == m_SortedItems.Count() - 1)
return;
int newItemID = m_SortedItems[i + 1]->GetID();
SetSelectedItem(m_Items[newItemID]);
ScrollToItem(newItemID);
}
void SectionedListPanel::MoveSelectionUp( void )
{
int itemID = GetSelectedItem();
Assert(itemID != -1);
if (!m_SortedItems.Count()) // if the list has been emptied
return;
int i;
for (i = 0; i < m_SortedItems.Count(); i++)
{
if (m_SortedItems[i]->GetID() == itemID)
break;
}
Assert(i != m_SortedItems.Count());
// we're already on the end
if (i == 0)
return;
int newItemID = m_SortedItems[i - 1]->GetID();
SetSelectedItem(m_Items[newItemID]);
ScrollToItem(newItemID);
}
//-----------------------------------------------------------------------------
// Purpose: arrow key movement handler
//-----------------------------------------------------------------------------
void SectionedListPanel::OnKeyCodeTyped(KeyCode code)
{
if (m_hEditModePanel.Get())
{
// ignore arrow keys in edit mode
// forward right up to parent so that tab focus change doesn't occur
CallParentFunction(new KeyValues("KeyCodeTyped", "code", code));
return;
}
int buttonTall = GetSectionTall();
if (code == KEY_DOWN)
{
MoveSelectionDown();
return;
}
else if (code == KEY_UP)
{
MoveSelectionUp();
return;
}
else if (code == KEY_PAGEDOWN)
{
// calculate info for # of rows
int cx, cy, cwide, ctall;
GetBounds(cx, cy, cwide, ctall);
int rowsperpage = ctall/buttonTall;
int itemID = GetSelectedItem();
int lastValidItem = itemID;
int secID = m_Items[itemID]->GetSectionID();
int i=0;
int row = m_SortedItems.Find(m_Items[itemID]);
while ( i < rowsperpage )
{
if ( m_SortedItems.IsValidIndex(++row) )
{
itemID = m_SortedItems[row]->GetID();
lastValidItem = itemID;
i++;
// if we switched sections, then count the section header as a row
if (m_Items[itemID]->GetSectionID() != secID)
{
secID = m_Items[itemID]->GetSectionID();
i++;
}
}
else
{
itemID = lastValidItem;
break;
}
}
SetSelectedItem(m_Items[itemID]);
ScrollToItem(itemID);
}
else if (code == KEY_PAGEUP)
{
// calculate info for # of rows
int cx, cy, cwide, ctall;
GetBounds(cx, cy, cwide, ctall);
int rowsperpage = ctall/buttonTall;
int itemID = GetSelectedItem();
int lastValidItem = itemID;
int secID = m_Items[itemID]->GetSectionID();
int i=0;
int row = m_SortedItems.Find(m_Items[itemID]);
while ( i < rowsperpage )
{
if ( m_SortedItems.IsValidIndex(--row) )
{
itemID = m_SortedItems[row]->GetID();
lastValidItem = itemID;
i++;
// if we switched sections, then count the section header as a row
if (m_Items[itemID]->GetSectionID() != secID)
{
secID = m_Items[itemID]->GetSectionID();
i++;
}
}
else
{
SetSelectedItem(m_Items[lastValidItem]);
m_pScrollBar->SetValue(0);
return;
}
}
SetSelectedItem(m_Items[itemID]);
ScrollToItem(itemID);
}
else if (code == KEY_LEFT || code == KEY_RIGHT)
{
}
else
{
BaseClass::OnKeyCodeTyped(code);
}
}
//-----------------------------------------------------------------------------
// Purpose: Clears the list
//-----------------------------------------------------------------------------
void SectionedListPanel::DeleteAllItems()
{
FOR_EACH_LL( m_Items, i )
{
m_Items[i]->SetVisible(false);
m_Items[i]->Clear();
// don't delete, move to free list
int freeIndex = m_FreeItems.AddToTail();
m_FreeItems[freeIndex] = m_Items[i];
}
m_Items.RemoveAll();
m_SortedItems.RemoveAll();
m_hSelectedItem = NULL;
InvalidateLayout();
m_bSortNeeded = true;
}
//-----------------------------------------------------------------------------
// Purpose: Changes the current list selection
//-----------------------------------------------------------------------------
void SectionedListPanel::SetSelectedItem(CItemButton *item)
{
if (m_hSelectedItem.Get() == item)
return;
// deselect the current item
if (m_hSelectedItem.Get())
{
m_hSelectedItem->SetSelected(false);
}
// set the new item
m_hSelectedItem = item;
if (m_hSelectedItem.Get())
{
m_hSelectedItem->SetSelected(true);
}
Repaint();
PostActionSignal(new KeyValues("ItemSelected", "itemID", m_hSelectedItem.Get() ? m_hSelectedItem->GetID() : -1));
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
int SectionedListPanel::GetSelectedItem()
{
if (m_hSelectedItem.Get())
{
return m_hSelectedItem->GetID();
}
return -1;
}
//-----------------------------------------------------------------------------
// Purpose: sets which item is currently selected
//-----------------------------------------------------------------------------
void SectionedListPanel::SetSelectedItem(int itemID)
{
if ( m_Items.IsValidIndex(itemID) )
{
SetSelectedItem(m_Items[itemID]);
}
}
//-----------------------------------------------------------------------------
// Purpose: returns the data of a selected item
//-----------------------------------------------------------------------------
KeyValues *SectionedListPanel::GetItemData(int itemID)
{
Assert(m_Items.IsValidIndex(itemID));
if ( !m_Items.IsValidIndex(itemID) )
return NULL;
return m_Items[itemID]->GetData();
}
//-----------------------------------------------------------------------------
// Purpose: returns what section an item is in
//-----------------------------------------------------------------------------
int SectionedListPanel::GetItemSection(int itemID)
{
if ( !m_Items.IsValidIndex(itemID) )
return -1;
return m_Items[itemID]->GetSectionID();
}
//-----------------------------------------------------------------------------
// Purpose: returns true if the itemID is valid for use
//-----------------------------------------------------------------------------
bool SectionedListPanel::IsItemIDValid(int itemID)
{
return m_Items.IsValidIndex(itemID);
}
//-----------------------------------------------------------------------------
// Purpose: returns true if the itemID is valid for use
//-----------------------------------------------------------------------------
int SectionedListPanel::GetHighestItemID()
{
return m_Items.MaxElementIndex();
}
//-----------------------------------------------------------------------------
// Purpose: item iterators
//-----------------------------------------------------------------------------
int SectionedListPanel::GetItemCount()
{
return m_SortedItems.Count();
}
//-----------------------------------------------------------------------------
// Purpose: item iterators
//-----------------------------------------------------------------------------
int SectionedListPanel::GetItemIDFromRow(int row)
{
if ( !m_SortedItems.IsValidIndex(row) )
return -1;
return m_SortedItems[row]->GetID();
}
//-----------------------------------------------------------------------------
// Purpose: returns the row that this itemID occupies. -1 if the itemID is invalid
//-----------------------------------------------------------------------------
int SectionedListPanel::GetRowFromItemID(int itemID)
{
for (int i = 0; i < m_SortedItems.Count(); i++)
{
if ( m_SortedItems[i]->GetID() == itemID )
{
return i;
}
}
return -1;
}
//-----------------------------------------------------------------------------
// Purpose: gets the local coordinates of a cell
//-----------------------------------------------------------------------------
bool SectionedListPanel::GetCellBounds(int itemID, int column, int &x, int &y, int &wide, int &tall)
{
x = y = wide = tall = 0;
if ( !IsItemIDValid(itemID) )
return false;
// get the item
CItemButton *item = m_Items[itemID];
if ( !item->IsVisible() )
return false;
//!! ignores column for now
item->GetBounds(x, y, wide, tall);
item->GetCellBounds(column, x, wide);
return true;
}
//-----------------------------------------------------------------------------
// Purpose: forces an item to redraw
//-----------------------------------------------------------------------------
void SectionedListPanel::InvalidateItem(int itemID)
{
if ( !IsItemIDValid(itemID) )
return;
m_Items[itemID]->InvalidateLayout();
m_Items[itemID]->Repaint();
}
//-----------------------------------------------------------------------------
// Purpose: set up a field for editing
//-----------------------------------------------------------------------------
void SectionedListPanel::EnterEditMode(int itemID, int column, vgui2::Panel *editPanel)
{
m_hEditModePanel = editPanel;
m_iEditModeItemID = itemID;
m_iEditModeColumn = column;
editPanel->SetParent(this);
editPanel->SetVisible(true);
editPanel->RequestFocus();
editPanel->MoveToFront();
InvalidateLayout();
}
//-----------------------------------------------------------------------------
// Purpose: leaves editing mode
//-----------------------------------------------------------------------------
void SectionedListPanel::LeaveEditMode()
{
if (m_hEditModePanel.Get())
{
InvalidateItem(m_iEditModeItemID);
m_hEditModePanel->SetVisible(false);
m_hEditModePanel->SetParent((Panel *)NULL);
m_hEditModePanel = NULL;
}
}
//-----------------------------------------------------------------------------
// Purpose: returns true if we are currently in inline editing mode
//-----------------------------------------------------------------------------
bool SectionedListPanel::IsInEditMode()
{
return (m_hEditModePanel.Get() != NULL);
}
//-----------------------------------------------------------------------------
// Purpose: list used to match indexes in image columns to image pointers
//-----------------------------------------------------------------------------
void SectionedListPanel::SetImageList(ImageList *imageList, bool deleteImageListWhenDone)
{
m_bDeleteImageListWhenDone = deleteImageListWhenDone;
m_pImageList = imageList;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void SectionedListPanel::OnSetFocus()
{
if (m_hSelectedItem.Get())
{
m_hSelectedItem->RequestFocus();
}
else
{
BaseClass::OnSetFocus();
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
int SectionedListPanel::GetSectionTall()
{
if (m_Sections.Count())
{
HFont font = m_Sections[0].m_pHeader->GetFont();
if (font != INVALID_FONT)
{
return surface()->GetFontTall(font) + BUTTON_HEIGHT_SPACER;
}
}
return BUTTON_HEIGHT_DEFAULT;
}
//-----------------------------------------------------------------------------
// Purpose: returns the size required to fully draw the contents of the panel
//-----------------------------------------------------------------------------
void SectionedListPanel::GetContentSize(int &wide, int &tall)
{
// make sure our layout is done
if (IsLayoutInvalid())
{
if (m_bSortNeeded)
{
ReSortList();
m_bSortNeeded = false;
}
LayoutPanels(m_iContentHeight);
}
wide = GetWide();
tall = m_iContentHeight;
}
//-----------------------------------------------------------------------------
// Purpose: Returns the index of a new item button
//-----------------------------------------------------------------------------
int SectionedListPanel::GetNewItemButton()
{
int itemID = m_Items.AddToTail();
if (m_FreeItems.Count())
{
// reusing an existing CItemButton
m_Items[itemID] = m_FreeItems[m_FreeItems.Head()];
m_Items[itemID]->SetID(itemID);
m_Items[itemID]->SetVisible(true);
m_FreeItems.Remove(m_FreeItems.Head());
}
else
{
// create a new CItemButton
m_Items[itemID] = SETUP_PANEL(new CItemButton(this, itemID));
}
return itemID;
}
//-----------------------------------------------------------------------------
// Purpose: Returns fallback font to use for text image for this column
// Input : sectionID -
// columnIndex -
// Output : virtual HFont
//-----------------------------------------------------------------------------
HFont SectionedListPanel::GetColumnFallbackFontBySection( int sectionID, int columnIndex )
{
int index = FindSectionIndexByID(sectionID);
if (index < 0)
return INVALID_FONT;
if (columnIndex >= m_Sections[index].m_Columns.Size())
return INVALID_FONT;
return m_Sections[index].m_Columns[columnIndex].m_hFallbackFont;
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/yoyojacky/CSMoE.git
git@gitee.com:yoyojacky/CSMoE.git
yoyojacky
CSMoE
CSMoE
master

搜索帮助