📄 listbox.cpp
字号:
//--------------------------------------------------
// Desc: ListBox
// Author: artsylee/2006.11.28
//--------------------------------------------------
#include "../stdafx.h"
#include "ListBox.h"
#include "../Core/Common.h"
#include "../Core/Input.h"
#include "../Core/IniFile.h"
#include "../Core/Graphics.h"
#include "../Core/TextureManager.h"
#include "../Core/Log.h"
#include "../Core/Message.h"
#include "../Core/Interface.h"
GListBox::GListBox(CWindow* pParent /* = NULL */):CWindow(pParent)
{
m_dwGUIType = GUI_LISTBOX;
m_pScroll = new GScrollBar(pParent);
m_dwStyle = MULTISELECTION;
m_nSelected = -1;
m_nSelStart = 0;
m_bDrag = false;
m_nBorder = 6;
m_nMargin = 5;
m_nTextHeight = 0;
m_hBack = INVALID_HANDLE;
m_hHighLight = INVALID_HANDLE;
}
GListBox::~GListBox()
{
RemoveAllItems();
delete m_pScroll;
if(g_pGUIManager)
{
g_pTextureManager->ReleaseTexture(m_hBack);
g_pTextureManager->ReleaseTexture(m_hHighLight);
}
}
bool GListBox::LoadFromIni(char* pfilename, char* pIndex)
{
CIniFile ui(pfilename);
m_dwID = ui.ReadDWORD(pIndex, "ID");
m_ptPos = ui.ReadPoint(pIndex, "Position");
m_rcSrc = ui.ReadRect(pIndex, "SrcRect");
m_dwColor = ui.ReadDWORD(pIndex, "Color", 0xffffffff);
m_dwAttrib = ui.ReadDWORD(pIndex, "Attrib", 10);
char texFile[256];
GRect zeroRc(0, 0, 0, 0);
// background
ui.ReadString(pIndex, "File", m_szUIPath);
DWORD index = ui.ReadDWORD(pIndex, "BackGround");
if(ui.IsReadSucceed())
m_hBack = LoadAMFTexture(m_szUIPath, index);
if(m_hBack==INVALID_HANDLE)
return false;
// highlight
index = ui.ReadDWORD(pIndex, "HighLight");
if(ui.IsReadSucceed())
m_hHighLight = LoadAMFTexture(m_szUIPath, index);
if(m_hHighLight==INVALID_HANDLE)
return false;
index = ui.ReadDWORD(pIndex, "Picture");
if(ui.IsReadSucceed())
{
m_hTexture = LoadAMFTexture(m_szUIPath, index);
if(m_rcSrc==zeroRc)
{
CTexture * ptex = g_pTextureManager->GetTexture(m_hTexture);
if(ptex)
{
m_rcSrc.SetRect(0, 0, ptex->GetWidth(), ptex->GetHeight());
}
}
}
if(m_rcSrc==zeroRc)
{
WriteLog(INFO_ERROR, "Can't Get m_rcSrc in file[%s] index[%s]", pfilename, pIndex);
return false;
}
ui.ReadString(pIndex, "ScrollBar", texFile);
m_pScroll->LoadFromIni(pfilename, texFile);
m_pScroll->SetSize(m_pScroll->GetMinWidth(), m_rcSrc.Height());
m_pScroll->MoveTo(m_ptPos.x+m_rcSrc.Width(), m_ptPos.y+m_pScroll->GetMinHeight());
if(m_pParent)
{
OffSet(m_pParent->GetRect().left, m_pParent->GetRect().top);
}
UpdateRect();
return m_Font.CreateFont("宋体", 12, 0, FW_BOLD);
}
void GListBox::UpdateRect()
{
m_rcSelection.SetRectWH(m_ptPos.x, m_ptPos.y, m_rcSrc.Width(), m_rcSrc.Height());
InflateRect(&m_rcSelection, -m_nBorder, -m_nBorder);
m_rcText = m_rcSelection;
InflateRect(&m_rcText, -m_nMargin, 0);
m_pScroll->SetPageSize(m_rcText.Height()/FONT_HEIGHT);
m_pScroll->ShowItem(m_nSelected);
}
void GListBox::SetBorder(int nBorder, int nMargin)
{
m_nBorder = nBorder;
m_nMargin = nMargin;
UpdateRect();
}
void GListBox::Render()
{
if(m_dwAttrib & GUI_VISIBLE)
{
// BackGround
GRect rc(m_ptPos.x, m_ptPos.y, m_ptPos.x+m_rcSrc.Width(), m_ptPos.y+m_rcSrc.Height());
g_pGraphics->RenderSprite(m_hTexture, &rc, NULL, m_dwColor);
// ScrollBar
m_pScroll->Render();
m_Font.Update();
// Text
RenderText();
}
return;
}
void GListBox::RenderText()
{
if(m_Items.size() > 0)
{
GRect rc = m_rcText;
GRect rcSel = m_rcSelection;
rc.bottom = rc.top + FONT_HEIGHT;
m_nTextHeight = rc.bottom - rc.top;
static bool bSBInit;
if(!bSBInit)
{
if(m_nTextHeight)
m_pScroll->SetPageSize(m_rcText.Height()/m_nTextHeight);
else
m_pScroll->SetPageSize(m_rcText.Height());
bSBInit = true;
}
rc.right = m_rcText.right;
for(int i=m_pScroll->GetTrackPos(); i<(int)m_Items.size(); i++)
{
if(rc.bottom > m_rcText.bottom)
break;
ListBoxItem *pItem = m_Items[i];
bool bSelectedStyle = false;
if(!(m_dwStyle & MULTISELECTION) && i == m_nSelected)
{
bSelectedStyle = true;
}
else if(m_dwStyle & MULTISELECTION)
{
/*
if(m_bDrag&&((i >= m_nSelected && i < m_nSelStart)||(i <= m_nSelected && i > m_nSelStart)))
{
bSelectedStyle = m_Items[m_nSelStart]->bSelected;
}
else if(pItem->bSelected)
{
bSelectedStyle = true;
}
*/
bSelectedStyle = pItem->bSelected;
}
if(bSelectedStyle)
{
rcSel.top = rc.top-2;
rcSel.bottom = rc.bottom-2;
rcSel.left = rc.left-m_nMargin;
//background
g_pGraphics->RenderSprite(m_hHighLight, &rcSel, NULL, 0xffffffff);
m_Font.DrawText(rc.left, rc.top, 0xffffffff, pItem->strText);
}
else
{
m_Font.DrawText(rc.left, rc.top, 0xffffff00, pItem->strText);
}
OffsetRect(&rc, 0, m_nTextHeight);
}
}
}
DWORD GListBox::ProcessEvent()
{
if(!(m_dwAttrib & GUI_VISIBLE) || !(m_dwAttrib & GUI_ENABLE) || m_hTexture==INVALID_HANDLE)
{
return INVALID_ID;
}
BOOL bAccess = m_pScroll->ProcessEvent();
switch(g_stInputInfo.MouseValue)
{
case LB_DOWN:
if(m_Items.size()>0 && CheckInRGN(m_rcSelection))
{
int nClicked;
if(m_nTextHeight)
nClicked = m_pScroll->GetTrackPos() + (g_stInputInfo.point.y - m_rcText.top)/m_nTextHeight;
else
nClicked = -1;
if(nClicked >= m_pScroll->GetTrackPos() &&
nClicked < (int)m_Items.size() &&
nClicked < m_pScroll->GetTrackPos() + m_pScroll->GetPageSize())
{
m_bDrag = true;
//处理双击
m_nSelected = nClicked;
if(!g_Input.GetKeyPtr()->IsKeyDown(DIK_LSHIFT))
{
m_nSelStart = m_nSelected;
}
if(m_dwStyle & MULTISELECTION)
{
ListBoxItem *pSelItem = m_Items[m_nSelected];
if(g_Input.GetKeyPtr()->IsKeyDown(DIK_LCONTROL) &&
!g_Input.GetKeyPtr()->IsKeyDown(DIK_LSHIFT))
{
// +Control Select
pSelItem->bSelected = !pSelItem->bSelected;
}
else if(g_Input.GetKeyPtr()->IsKeyDown(DIK_LSHIFT) &&
!g_Input.GetKeyPtr()->IsKeyDown(DIK_LCONTROL))
{
// +Shift Select
int nBegin = m_nSelStart<m_nSelected?m_nSelStart:m_nSelected;
int nEnd = m_nSelStart>m_nSelected?m_nSelStart:m_nSelected;
for(int i=0; i<nBegin; i++)
{
m_Items[i]->bSelected = false;
}
for(int i=nEnd+1; i<(int)m_Items.size(); i++)
{
m_Items[i]->bSelected = false;
}
for(int i=nBegin; i<=nEnd; i++)
{
m_Items[i]->bSelected = true;
}
}
else if(g_Input.GetKeyPtr()->IsKeyDown(DIK_LSHIFT) &&
g_Input.GetKeyPtr()->IsKeyDown(DIK_LCONTROL))
{
// +Shift +Control Select
int nBegin = m_nSelStart<m_nSelected?m_nSelStart:m_nSelected;
int nEnd = m_nSelStart>m_nSelected?m_nSelStart:m_nSelected;
bool bLastSelected = m_Items[m_nSelStart]->bSelected;
for(int i=nBegin+1; i<nEnd; i++)
{
m_Items[i]->bSelected = bLastSelected;
}
pSelItem->bSelected = true;
m_nSelected = m_nSelStart;
}
else
{
// common click
for(int i=0; i<(int)m_Items.size(); i++)
{
m_Items[i]->bSelected = false;
}
pSelItem->bSelected = true;
}
}
// POST MESSAGE
//发送ValueChange信息
CMessage msg(MSG_SYS_GUI, m_dwID);
msg.SetParameter(GUI_VALUE_CHANGE, m_nSelected, this);
PostMessage(msg);
}
bAccess = TRUE;
}
break;
case LB_UP:
{
m_bDrag = false;
}
break;
}
if(bAccess)
return m_dwID;
else
return INVALID_ID;
}
void GListBox::OffSet(int x, int y)
{
CWindow::OffSet(x, y);
m_pScroll->OffSet(x, y);
UpdateRect();
}
bool GListBox::AddItem(char *szText, void *pData)
{
ListBoxItem *pItem = new ListBoxItem;
if(!pItem)
return false;
strcpy(pItem->strText, szText);
pItem->pData = pData;
SetRect(&pItem->rcActive, 0, 0, 0, 0);
pItem->bSelected = false;
m_Items.push_back(pItem);
m_pScroll->SetTrackRange(0, m_Items.size());
return true;
}
bool GListBox::InsertItem(int nIndex, char *szText, void *pData)
{
ListBoxItem *pItem = new ListBoxItem;
if(!pItem)
return false;
if(nIndex<0 || nIndex>=(int)m_Items.size())
return false;
strcpy(pItem->strText, szText);
pItem->pData = pData;
SetRect(&pItem->rcActive, 0, 0, 0, 0);
pItem->bSelected = false;
m_Items.insert(m_Items.begin()+nIndex, pItem);
m_pScroll->SetTrackRange(0, (int)m_Items.size());
return true;
}
void GListBox::RemoveItem(int nIndex)
{
if(nIndex<0 || nIndex>=(int)m_Items.size())
return;
std::vector<ListBoxItem*>::iterator itor = m_Items.begin();
itor += nIndex;
delete (*itor);
m_Items.erase(itor);
m_pScroll->SetTrackRange(0, (int)m_Items.size());
if(m_nSelected >= (int)m_Items.size())
{
m_nSelected = m_Items.size()-1;
}
// Post Messsage
}
void GListBox::RemoveAllItems()
{
std::vector<ListBoxItem*>::iterator itor = m_Items.begin();
while(itor!=m_Items.end())
{
delete (*itor);
itor++;
}
m_Items.clear();
m_pScroll->SetTrackRange(0, 1);
}
ListBoxItem* GListBox::GetItem(int nIndex)
{
if(nIndex < 0 || nIndex >= (int)m_Items.size())
return NULL;
return m_Items[nIndex];
}
int GListBox::GetSelectedIndex(int nPreviousSelected /* = -1 */)
{
if(nPreviousSelected < -1)
return -1;
if(m_dwStyle & MULTISELECTION)
{
for(int i=nPreviousSelected+1; i<(int)m_Items.size(); i++)
{
ListBoxItem *pItem = m_Items[i];
if(pItem->bSelected)
return i;
}
return -1;
}
else
{
return m_nSelected;
}
}
ListBoxItem* GListBox::GetSelectedItem(int nPreviousSelected /* = -1 */)
{
return GetItem(GetSelectedIndex(nPreviousSelected));
}
void GListBox::SelectItem(int nNewIndex, bool bPost /* = false */)
{
if(m_Items.size() == 0)
return;
int nOldSelected = m_nSelected;
m_nSelected = nNewIndex;
if(m_nSelected<0)
m_nSelected = 0;
if(m_nSelected>=(int)m_Items.size())
m_nSelected = m_Items.size() - 1;
if(nOldSelected != m_nSelected)
{
if(m_dwStyle & MULTISELECTION)
{
m_Items[m_nSelected]->bSelected = true;
}
m_nSelStart = m_nSelected;
m_pScroll->ShowItem(m_nSelected);
}
//POST MESSAGE
if(bPost)
{
CMessage msg(MSG_SYS_GUI, m_dwID);
msg.SetParameter(GUI_VALUE_CHANGE, m_nSelected, this);
PostMessage(msg);
}
}
//--------------------------------------------------
// COOL LISTBOX
//--------------------------------------------------
CoolListBox::CoolListBox(CWindow* pParent /* = NULL */):GListBox(pParent)
{
if(m_pScroll != NULL)
{
delete m_pScroll;
m_pScroll = NULL;
}
m_pScroll = new CoolScroll(pParent);
m_dwGUIType = GUI_COOLLISTBOX;
m_nBorder = 12;
m_WindowBorder = 0;
}
bool CoolListBox::LoadFromIni(char* pfilename, char* pIndex)
{
if(GListBox::LoadFromIni(pfilename, pIndex))
{
CTexture *pTex = g_pTextureManager->GetTexture(m_hTexture);
if(pTex)
{
m_WindowBorder = pTex->GetHeight();
if(m_WindowBorder==8) m_WindowCull = 3;
if(m_WindowBorder==16) m_WindowCull = 5;
if(m_WindowBorder==32) m_WindowCull = 10;
}
m_pScroll->SetSize(m_pScroll->GetMinWidth(), m_rcSrc.Height()+12);
m_pScroll->MoveTo(m_ptPos.x+m_rcSrc.Width()-6, m_ptPos.y+m_pScroll->GetMinHeight()-6);
return true;
}
return false;
}
void CoolListBox::Render()
{
if(m_dwAttrib & GUI_VISIBLE)
{
// BackGround
GRect dst;
RECT rcWnd = { m_ptPos.x, m_ptPos.y, m_ptPos.x+m_rcSrc.Width(), m_ptPos.y+m_rcSrc.Height() };
dst.SetRectWH(rcWnd.left+m_WindowCull, rcWnd.top+m_WindowCull, (rcWnd.right-rcWnd.left)-m_WindowCull*2, (rcWnd.bottom-rcWnd.top)-m_WindowCull*2);
g_pGraphics->RenderSprite(m_hBack, &dst, NULL, m_dwColor);
// Text
RenderText();
// Border
CWindow::RenderNewStyle(m_hTexture, rcWnd, m_dwColor, m_WindowBorder);
// ScrollBar
m_pScroll->Render();
m_Font.Update();
}
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -