⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 listbox.cpp

📁 3D游戏展示程序
💻 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 + -