PanelList cpp
Jump to navigation
Jump to search
/////////// Copyright © 2007, Mark Chandler. All rights reserved. ///////////
//
// Description:
//
//
// Mark Chandler 2007 admin@lodle.net
//
////////////////////////////////////////////////////////////////////////////////
#include "cbase.h"
#include "pd_panel_list.h"
////////////////////////////////////////////////////////////////////////////////
// Constructor
////////////////////////////////////////////////////////////////////////////////
PD_PanelList::PD_PanelList(Panel *parent, const char *name) : Panel(parent, name)
{
this->SetPaintBackgroundEnabled( false );
this->SetPaintBackgroundType( 0 );
this->SetPaintBorderEnabled(true);
this->SetKeyBoardInputEnabled( true );
m_pScrollBar = new vgui::ScrollBar( this, "Scrollbar", true);
m_pScrollBar->AddActionSignalTarget(this);
m_pSelImage = new PD_BasePanel( this, "SelectImage");
m_iMargen = 5;
m_iGroupMargen = 20;
m_iSelected =-1;
m_iHeight = 20;
m_iMaxSliderVal = 0;
m_pSelImage->SetVisible( false );
m_pSelImage->bgColor = new Color(50, 100, 255, 125) ;
m_pSelImage->SetZPos(100);
m_pSelImage->AddActionSignalTarget(this);
updateSize();
m_bHeaderDisabled = false;
m_bShowSelected = true;
m_bFixedSize = true;
m_bRejectSliderMove = false;
m_bPaintBg = true;
}
////////////////////////////////////////////////////////////////////////////////
// Destructor
////////////////////////////////////////////////////////////////////////////////
PD_PanelList::~PD_PanelList()
{
}
int PD_PanelList::AddPanel( Panel* pPanel, bool isSelectable)
{
return AddPanel(pPanel, NULL, isSelectable);
}
int PD_PanelList::AddPanel( Panel* pPanel, char* header, bool isSelectable)
{
int headId = -1;
if (header!=NULL)
{
headId = FindHeaderUsingIdent(header);
if (headId == -1) //if header doesnt exsist make it
{
vgui::Panel* pPanel=new PD_HeaderPanel(this, header);
pPanel->SetZPos(25);
headId = m_pHeaderList.AddToTail(pPanel);
}
}
int id = FindItemUsingIdent(pPanel->GetName());
if (id != -1)
return -1;
pPanel->SetParent( this );
pPanel->SetVisible(true);
pPanel->SetPaintBackgroundEnabled( true );
pPanel->SetPaintBackgroundType( 0 );
pPanel->SetPaintBorderEnabled(true);
pPanel->AddActionSignalTarget(this);
pPanel->SetZPos(50);
panelInfo* newPanel= new panelInfo;
newPanel->iHeader = headId;
newPanel->pPanel = pPanel;
newPanel->isSelectable = isSelectable;
int index = m_pPanelList.AddToTail( newPanel );
ResetAllChildPos();
//Msg("Scroll bar range is: %d\n", range);
return index;
}
void PD_PanelList::ResetAllChildPos( )
{
m_iSelected = 0;
if (m_bHeaderDisabled)
{
int heightCount = 0;
int iLastHeight=0;
for(int i = 0; i < m_pPanelList.Count();i++)
{
vgui::Panel *pItem = m_pPanelList[i]->pPanel;
int x,y;
int tall=0;
if (i <= 0)
{
if (m_bFixedSize)
y=-1*(m_iHeight + m_iMargen);
else
y=-1*m_iMargen;
}
else
{
m_pPanelList[i-1]->pPanel->GetPos(x,y);
}
int ypos=y + m_iMargen +m_iMargen;
if (m_bFixedSize)
{
ypos += m_iHeight;
tall = m_iHeight;
}
else
{
ypos += iLastHeight;
tall = m_pPanelList[i]->pPanel->GetTall();
iLastHeight = tall;
heightCount += tall;
}
pItem->SetBounds(m_iMargen, ypos, GetWide()-m_iMargen-m_iMargen-m_pScrollBar->GetWide(), tall);
}
for(int i = 0; i < m_pHeaderList.Count();i++)
{
m_pHeaderList[i]->SetVisible(false);
}
if (m_bFixedSize)
m_iMaxSliderVal = m_pPanelList.Count()*m_iHeight+m_pPanelList.Count()*m_iMargen+m_iMargen;
else
m_iMaxSliderVal = heightCount + m_pPanelList.Count()*m_iMargen + m_iMargen;
m_pScrollBar->SetRange(0, m_iMaxSliderVal);
}
else
{
int maxGroups = m_pHeaderList.Count();
//Msg("maxGroups is %d\n", maxGroups);
if (maxGroups==0)
return;
for (int i=0; i<maxGroups; i++)
{
//Msg("I is %d\n", i);
int count=0;
int heightCount=0;
for (int j=0; j<m_pPanelList.Count(); j++ )
{
//Msg("%d: [%d] == [%d]\n",j, m_pPanelList[j]->iHeader , i);
if (m_pPanelList[j]->iHeader == i)
{
heightCount += m_pPanelList[j]->pPanel->GetTall();
count++;
}
}
//Msg("I is %d, Count is %d\n", i, count);
int x,y;
if (i <= 0)
{
x=0;
y=-1*m_iGroupMargen + m_iMargen;
}
else
{
m_pHeaderList[i-1]->GetPos(x,y);
y += m_pHeaderList[i-1]->GetTall();
}
//Msg("I is %d\n", i);
int tall =0;
if (m_bFixedSize)
tall = (count+1)*m_iMargen + count*m_iHeight + TITLEHIEGHT;
else
tall = (count+1)*m_iMargen + heightCount + TITLEHIEGHT;
int ypos = y + m_iGroupMargen;
if (m_pHeaderList[i])
{
m_pHeaderList[i]->SetVisible(true);
m_pHeaderList[i]->SetBounds(m_iMargen, ypos, GetWide()-(m_iMargen*2)-m_pScrollBar->GetWide(), tall);
}
int lastypos =0;
int iLastHeight=0;
if (m_bFixedSize)
lastypos = ypos + -1*(m_iHeight) + TITLEHIEGHT;
else
lastypos = ypos + TITLEHIEGHT;
for (int j=0; j<m_pPanelList.Count(); j++ )
{
if (m_pPanelList[j]->iHeader == i)
{
vgui::Panel *pItem = m_pPanelList[j]->pPanel;
int ypos = 0;
if (m_bFixedSize)
ypos = lastypos + m_iMargen + m_iHeight;
else
ypos = lastypos + m_iMargen + iLastHeight;
lastypos = ypos;
if (m_bFixedSize)
pItem->SetBounds(m_iMargen*2, ypos, GetWide()-(m_iMargen*4)-m_pScrollBar->GetWide(), m_iHeight);
else
{
iLastHeight = pItem->GetTall();
pItem->SetBounds(m_iMargen*2, ypos, GetWide()-(m_iMargen*4)-m_pScrollBar->GetWide(), iLastHeight);
}
}
}
}
m_iMaxSliderVal = 0;
for (int i=0; i<maxGroups; i++)
{
m_iMaxSliderVal+=m_pHeaderList[i]->GetTall();
}
m_iMaxSliderVal+=m_iGroupMargen;
m_pScrollBar->SetRange(0, m_iMaxSliderVal);
}
}
void PD_PanelList::SetSelected( int index )
{
if (index >= 0 && index < m_pPanelList.Count() && m_pPanelList[index]->isSelectable == true)
m_iSelected = index;
}
void PD_PanelList::SetMargen( int amount )
{
if (this->IsProportional())
m_iMargen = scheme()->GetProportionalScaledValue(amount);
else
m_iMargen = amount;
updateSize();
}
void PD_PanelList::SetHeight( int amount )
{
if (this->IsProportional())
m_iHeight = scheme()->GetProportionalScaledValue(amount);
else
m_iHeight = amount;
updateSize();
}
void PD_PanelList::PurgeAll( void )
{
for (int x=0; x<m_pPanelList.Count(); x++)
{
delete m_pPanelList[x]->pPanel;
}
//for (int x=0; x<m_pHeaderList.Count(); x++)
//{
// delete m_pHeaderList[x];
//}
m_pPanelList.PurgeAndDeleteElements();
m_pHeaderList.PurgeAndDeleteElements();
m_iSelected =-1;
m_pScrollBar->SetRange(0,0);
m_iMaxSliderVal = 0;
}
void PD_PanelList::Reset()
{
}
void PD_PanelList::OnSizeChanged(int newWide, int newTall)
{
m_pScrollBar->SetBounds(newWide-m_pScrollBar->GetWide(), 0, m_pScrollBar->GetWide(), newTall);
for(int i = 0; i < m_pPanelList.Count();i++)
{
m_pPanelList[i]->pPanel->SetWide(newWide-m_iMargen-m_iMargen-m_pScrollBar->GetWide());
}
m_pScrollBar->SetRangeWindow(GetTall()-m_iMargen-m_iMargen);
ResetAllChildPos();
}
void PD_PanelList::OnThink( void )
{
Update();
BaseClass::OnThink();
}
void PD_PanelList::OnCommand(char* command)
{
//Msg("Panel List Command: %s\n", command);
if (strcmp(command,"UpdatePos")==0)
{
ResetAllChildPos();
}
else if ( GetVParent() )
{
KeyValues *msg = new KeyValues("Command");
msg->SetString("command", command);
PostActionSignal( msg );
};
}
void PD_PanelList::OnRequestUpdate(const char* PanelName)
{
ResetAllChildPos();
//OnItemClicked( PanelName );
}
void PD_PanelList::Update( void )
{
if (!m_pPanelList.Count())
return;
int range = m_pPanelList.Count()*m_iHeight+m_pPanelList.Count()*m_iMargen+m_iMargen;
if (range < GetTall())
m_pScrollBar->SetEnabled( false );
else
m_pScrollBar->SetEnabled(true);
}
void PD_PanelList::OnSliderMoved(int value)
{
if (m_bRejectSliderMove)
{
m_bRejectSliderMove=false;
return;
}
//Msg("Moving to: %d [%d] [%d]\n", value, m_iMaxSliderVal, GetTall());
if (value < 0)
value = 0;
if (value > m_iMaxSliderVal)
value = m_iMaxSliderVal;
int x,y;
if (m_bHeaderDisabled == true)
m_pPanelList[0]->pPanel->GetPos(x, y);
else
m_pHeaderList[0]->GetPos(x, y);
int ammount = -1*(value+(y-m_iMargen));
//stops an loop happning where moveby updates slider and makes it move again.
m_bRejectSliderMove = true;
MoveBy(ammount, true );
}
void PD_PanelList::ResetSelected()
{
if (m_iSelected != -1 && m_bShowSelected)
{
int x,y;
m_pPanelList[m_iSelected]->pPanel->GetPos(x,y);
m_pSelImage->SetVisible( true );
int tall=m_iMargen+m_iMargen;
if (m_bFixedSize)
tall += m_iHeight;
else
tall += m_pPanelList[m_iSelected]->pPanel->GetTall();
m_pSelImage->SetBounds(m_iMargen, y-m_iMargen, GetWide()-m_pScrollBar->GetWide()-m_iMargen-m_iMargen, tall);
}
else
{
m_pSelImage->SetVisible( false );
}
}
void PD_PanelList::UpdateSelected()
{
// make sure selected is allways shown
if (m_iSelected != -1)
{
int x,y;
m_pPanelList[m_iSelected]->pPanel->GetPos(x,y);
if (m_bFixedSize)
{
if (y+m_iHeight > GetTall())
MoveBy( -1 *((y+m_iHeight+m_iMargen) - GetTall()));
}
else
{
int tall = m_pPanelList[m_iSelected]->pPanel->GetTall();
//Msg("Im %d tall\n", tall);
if (y+tall+m_iMargen > GetTall())
MoveBy( -1 *((y+tall+m_iMargen) - GetTall()));
}
if (y < 0)
MoveBy( -y + m_iMargen );
}
ResetSelected();
InvalidateLayout();
}
void PD_PanelList::MoveBy( int amount, bool slider )
{
int x,y;
for (int i=0; i<m_pPanelList.Count(); i++)
{
m_pPanelList[i]->pPanel->GetPos(x, y);
m_pPanelList[i]->pPanel->SetPos(x, y+amount);
}
for (int i=0; i<m_pHeaderList.Count(); i++)
{
m_pHeaderList[i]->GetPos(x, y);
m_pHeaderList[i]->SetPos(x, y+amount);
}
if (!slider)
{
m_pPanelList[0]->pPanel->GetPos(x, y);
m_pScrollBar->SetValue(abs(y-m_iMargen));
}
ResetSelected();
InvalidateLayout();
}
#define BORDERWIDTH 1
void PD_PanelList::Paint()
{
BaseClass::Paint();
PaintBorder();
}
void PD_PanelList::PaintBackground()
{
if (!m_bPaintBg)
return;
int wide, tall;
GetSize(wide, tall);
vgui::surface()->DrawSetColor(Color(120,120,120,255));
vgui::surface()->DrawFilledRect(0, 0, wide, tall);
}
void PD_PanelList::PaintBorder()
{
int wide, tall;
GetSize(wide, tall);
int sw = m_pScrollBar->GetWide();
surface()->DrawSetColor( Color(0,200,255,255) );
////draw top
surface()->DrawFilledRect(BORDERWIDTH, 0, wide-sw, BORDERWIDTH);
//draw bottom
surface()->DrawFilledRect(BORDERWIDTH, tall-BORDERWIDTH, wide-sw, tall);
//draw left
surface()->DrawFilledRect(0, 0, BORDERWIDTH, tall);
//draw right
//surface()->DrawFilledRect(wide-BORDERWIDTH-BORDERINSTEP, captionHeight+1, wide-BORDERINSTEP, tall);
}
void PD_PanelList::updateSize( void )
{
OnSizeChanged(GetWide(), GetTall());
}
int PD_PanelList::FindItemUsingIdent(const char *pszIdent)
{
for(int i = 0; i < m_pPanelList.Count();i++)
{
vgui::Panel *pItem = m_pPanelList[i]->pPanel;
if(pItem == NULL)
continue;
if(strcmp(pszIdent,pItem->GetName())==0)
return i;
//Msg("Comparing: [%s], [%s]\n", pszIdent,pItem->GetName());
}
return -1;
}
int PD_PanelList::FindHeaderUsingIdent(const char *pszIdent)
{
for(int i = 0; i < m_pHeaderList.Count();i++)
{
vgui::Panel *pItem = m_pHeaderList[i];
//headerInfo* pItem = m_pHeaderList[i];
if(pItem == NULL)
continue;
if(strcmp(pszIdent,pItem->GetName())==0)
return i;
//Msg("Comparing: [%s], [%s]\n", pszIdent,pItem->GetName());
}
return -1;
}
void PD_PanelList::PrintLoc()
{
for(int i = 0; i < m_pPanelList.Count();i++)
{
int x,y;
m_pPanelList[i]->pPanel->GetPos(x,y);
Msg("Panel %d, X:%d, Y:%d\n",i,x,y);
}
}
void PD_PanelList::OnKeyCodeTyped(KeyCode code)
{
//Msg("KeyCode %d\n", code);
if ( code == KEY_W || code == KEY_UP)
{
if (m_pPanelList.Count() > 0)
{
if (m_iSelected == -1)
SetSelected(0);
if (m_iSelected != 0)
SetSelected(m_iSelected-1);
}
else
{
m_iSelected=-1;
}
UpdateSelected();
}
else if ( code == KEY_S || code == KEY_DOWN)
{
if (m_pPanelList.Count() > 0)
{
if (m_iSelected < m_pPanelList.Count()-1)
SetSelected(m_iSelected+1);
}
else
{
m_iSelected=-1;
}
UpdateSelected();
}
//ShowSelected();
}
void PD_PanelList::OnCursorMoved( int x, int y)
{
}
void PD_PanelList::OnMouseWheeled(int delta)
{
delta*=-1;
if (m_pPanelList.Count() > 0)
{
if (m_iSelected == -1)
m_iSelected = 0;
else if ((m_iSelected + delta) >= 0 && (m_iSelected +delta) < m_pPanelList.Count())
SetSelected(m_iSelected+delta);
}
else
{
m_iSelected=-1;
}
UpdateSelected();
}
void PD_PanelList::OnSetSelected(const char* name)
{
OnItemClicked(name);
}
void PD_PanelList::OnItemClicked(const char* name)
{
int id = FindItemUsingIdent( name );
SetSelected(id);
UpdateSelected();
}
void PD_PanelList::OnItemDoubleClicked(const char* name)
{
//SetSelected(FindItemUsingIdent(name));
KeyValues *msg = new KeyValues("Command");
msg->SetString("command", "Select");
PostActionSignal( msg );
//PostActionSignal(new KeyValues("ItemDoubleClick","name", this->GetName()));
}
//void PD_PanelList::OnMouseDoublePressed(MouseCode code)
//{
// Msg("Mouse clicked\n");
//}
/////////////////////////////////////////////////////////////////////////////////////////////////////
PD_HeaderPanel::PD_HeaderPanel(Panel *parent, const char *name) : PD_BasePanel(parent, name)
{
m_pTitleBG = new vgui::ImagePanel(this, "TitleBG");
m_pTitleBG->SetFillColor(Color(255,255,0,255));
m_pTitleBG->SetShouldScaleImage( true );
m_pBodyBG = new vgui::ImagePanel(this, "BodyBG");
m_pBodyBG->SetFillColor(Color(255,0,255,0));
m_pBodyBG->SetVisible( false );
m_pTitle = new vgui::Label(this, "TitleLabel", "[title]");
m_pTitle->SetMouseInputEnabled(false);
m_bNeedsUpdate = true;
Q_strncpy(m_szTitle,"NULL NAME", 256);
OnSizeChanged(GetWide(), GetTall());
}
void PD_HeaderPanel::OnThink( void )
{
if (m_bNeedsUpdate)
{
m_pTitleBG->SetImage( HEADERIMG );
m_pTitle->SetText(GetName());
//m_pTitle->SetFgColor(Color(0,0,0,255));
m_bNeedsUpdate = false;
}
}
void PD_HeaderPanel::PaintBackground()
{
return;
//int wide, tall;
//GetSize(wide, tall);
//vgui::surface()->DrawSetColor(Color(120,120,120,255));
//vgui::surface()->DrawFilledRect(0, 0, wide, tall);
}
void PD_HeaderPanel::OnSizeChanged(int newWide, int newTall)
{
m_pTitle->SetBounds( 10, 0, newWide, TITLEHIEGHT);
m_pTitleBG->SetBounds(0,0,newWide, TITLEHIEGHT);
m_pBodyBG->SetBounds(0,TITLEHIEGHT,newWide, newTall-TITLEHIEGHT);
}