📄 wg_listbox.cpp
字号:
// wg_listbox.cpp//// CListBox class implementation////// Copyright (c) 2002 Rob Wiskow// rob-dev@boxedchaos.com//// This library is free software; you can redistribute it and/or// modify it under the terms of the GNU Lesser General Public// License as published by the Free Software Foundation; either// version 2.1 of the License, or (at your option) any later version.//// This library is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU// Lesser General Public License for more details.//// You should have received a copy of the GNU Lesser General Public// License along with this library; if not, write to the Free Software// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA//#include "wgui_include_config.h"#include "wg_listbox.h"#include "wg_application.h"#include "wg_message_server.h"#include "wg_error.h"#include "wg_debug.h"namespace wGui{CListBox::CListBox(const CRect& WindowRect, CWindow* pParent, bool bSingleSelection, unsigned int iItemHeight, CFontEngine* pFontEngine) : CWindow(WindowRect, pParent), m_iItemHeight(iItemHeight), m_iFocusedItem(0), m_bSingleSelection(bSingleSelection), m_pDropDown(0){ m_sClassName = "CListBox"; if (pFontEngine) { m_pFontEngine = pFontEngine; } else { m_pFontEngine = CApplication::Instance()->GetDefaultFontEngine(); } CRect ScrollbarRect(m_WindowRect); ScrollbarRect.Grow(-1); m_pVScrollbar = new CScrollBar( CRect(ScrollbarRect.Right() - 12, ScrollbarRect.Top(), ScrollbarRect.Right(), ScrollbarRect.Bottom()) , this, CScrollBar::VERTICAL), m_pVScrollbar->SetLimits(0, 0); m_ClientRect = CRect(2, 2, m_WindowRect.Width() - 16, m_WindowRect.Height() - 4); m_BGColor = COLOR_WHITE; CMessageServer::Instance().RegisterMessageClient(this, CMessage::KEYBOARD_KEYDOWN); CMessageServer::Instance().RegisterMessageClient(this, CMessage::CTRL_VALUECHANGE); CMessageServer::Instance().RegisterMessageClient(this, CMessage::CTRL_VALUECHANGING);}CListBox::~CListBox(void){ delete m_pVScrollbar;}void CListBox::SetItemHeight(unsigned int iItemHeight){ m_iItemHeight = iItemHeight; StartDrawProc();}int CListBox::AddItem(SListItem ListItem){ m_Items.push_back(ListItem); m_SelectedItems.push_back(false); m_RenderedStrings.push_back(CRenderedString(m_pFontEngine, ListItem.sItemText, CRenderedString::VALIGN_TOP, CRenderedString::HALIGN_LEFT)); int iMax = (m_Items.size() - 1) < 0 ? 0 : static_cast<int>(m_Items.size() - 1); m_pVScrollbar->SetLimits(0, iMax); StartDrawProc(); return static_cast<int>(m_Items.size());}void CListBox::RemoveItem(int iItemIndex){ m_Items.erase(m_Items.begin() + iItemIndex); m_SelectedItems.erase(m_SelectedItems.begin() + iItemIndex); int iMax = (m_Items.size() - 1) < 0 ? 0 : static_cast<int>(m_Items.size() - 1); m_pVScrollbar->SetLimits(0, iMax); StartDrawProc();}void CListBox::ClearItems(void){ m_Items.clear(); m_SelectedItems.clear(); m_pVScrollbar->SetLimits(0, 0); StartDrawProc();}void CListBox::SetAllSelections(bool bSelected){ for (unsigned int i = 0; i < m_Items.size(); ++i) { m_SelectedItems[i] = bSelected; }}void CListBox::Draw(void) const{ CWindow::Draw(); CPainter Painter(m_pSDLSurface); Painter.DrawRect(m_WindowRect, false, COLOR_BLACK); CRect ClientRect(GetClientRect()); int iStartIndex = m_pVScrollbar->GetPosition(); for (unsigned int i = iStartIndex; i < m_Items.size(); ++i) { CRect ItemRect(ClientRect.Left(), ClientRect.Top() + (i - iStartIndex) * m_iItemHeight, ClientRect.Right(), ClientRect.Top() + (i - iStartIndex + 1) * m_iItemHeight - 1); if (ItemRect.Overlaps(GetClientRect())) { ItemRect.ClipTo(GetClientRect()); ItemRect.SetBottom(ItemRect.Bottom() - 1); if (m_SelectedItems[i]) { Painter.DrawRect(ItemRect, true, COLOR_LIGHTGRAY, COLOR_LIGHTGRAY); } if (static_cast<int>(i) == m_iFocusedItem) { ItemRect.Grow(1); Painter.DrawRect(ItemRect, false, COLOR_BLACK); ItemRect.Grow(-1); } ItemRect.Grow(-1); m_RenderedStrings[i].Draw(m_pSDLSurface, ItemRect, ItemRect.TopLeft() + CPoint(0, 1), m_Items[i].ItemColor); } }}void CListBox::SetWindowRect(const CRect& WindowRect){ CWindow::SetWindowRect(WindowRect); CRect ScrollbarRect(m_WindowRect); ScrollbarRect.Grow(-1); m_pVScrollbar->SetWindowRect(CRect(ScrollbarRect.Right() - 12, ScrollbarRect.Top(), ScrollbarRect.Right(), ScrollbarRect.Bottom())); m_ClientRect = CRect(2, 2, m_WindowRect.Width() - 16, m_WindowRect.Height() - 4);}bool CListBox::OnMouseButtonDown(CPoint Point, unsigned int Button){ bool bResult = false; if (! CWindow::OnMouseButtonDown(Point, Button) && m_bVisible && (m_WindowRect.HitTest(Point) == CRect::RELPOS_INSIDE) && (Button == CMouseMessage::LEFT)) { if (CApplication::Instance()->GetKeyFocus() != this) { CApplication::Instance()->SetKeyFocus(this); } CRect ClientRect(GetClientRect()); if (!m_Items.empty() && ClientRect.HitTest(Point) == CRect::RELPOS_INSIDE) { // Prep the new selection m_iFocusedItem = (Point.YPos() - ClientRect.Top()) / m_iItemHeight + m_pVScrollbar->GetPosition(); StartDrawProc(); } bResult = true; } return bResult;}bool CListBox::OnMouseButtonUp(CPoint Point, unsigned int Button){ bool bResult = false; CRect ClientRect(GetClientRect()); if (! CWindow::OnMouseButtonUp(Point, Button) && m_bVisible && (ClientRect.HitTest(Point) == CRect::RELPOS_INSIDE) && (Button == CMouseMessage::LEFT)) { if (m_iFocusedItem == static_cast<int>((Point.YPos() - ClientRect.Top()) / m_iItemHeight + m_pVScrollbar->GetPosition())) { if (m_bSingleSelection) { SetAllSelections(false); } SetSelection(m_iFocusedItem, ! IsSelected(m_iFocusedItem)); CWindow* pDestination = m_pParentWindow; if (m_pDropDown) { pDestination = m_pDropDown; } CMessageServer::Instance().QueueMessage(new TIntMessage(CMessage::CTRL_VALUECHANGE, pDestination, this, m_iFocusedItem)); StartDrawProc(); } bResult = true; } return bResult;}bool CListBox::HandleMessage(CMessage* pMessage){ bool bHandled = false; if (pMessage) { switch(pMessage->MessageType()) { case CMessage::KEYBOARD_KEYDOWN: { CKeyboardMessage* pKeyMsg = dynamic_cast<CKeyboardMessage*>(pMessage); if (pKeyMsg && pMessage->Destination() == this) { switch (pKeyMsg->Key) { case SDLK_DOWN: { if (m_iFocusedItem + 1 < Size()) { m_iFocusedItem++; int diff = m_iFocusedItem - m_pVScrollbar->GetPosition(); CRect ClientRect(GetClientRect()); if (m_iItemHeight * (m_pVScrollbar->GetPosition() + diff + 1) > (unsigned int) ClientRect.Height()) { m_pVScrollbar->SetPosition(m_pVScrollbar->GetPosition() + 1); } StartDrawProc(); bHandled = true; } break; } case SDLK_UP: { if ( m_iFocusedItem > 0 ) { m_iFocusedItem--; if (m_iFocusedItem < m_pVScrollbar->GetPosition()) { m_pVScrollbar->SetPosition(m_pVScrollbar->GetPosition() - 1); } StartDrawProc(); bHandled = true; } break; } case SDLK_PAGEDOWN: { CRect ClientRect(GetClientRect()); int nSize = Size() - 1; int nItemsPerPage = ClientRect.Height() / m_iItemHeight; if (m_iFocusedItem + nItemsPerPage < nSize) { m_iFocusedItem += nItemsPerPage; } else { m_iFocusedItem = nSize; } m_pVScrollbar->SetPosition(m_iFocusedItem); StartDrawProc(); bHandled=true; break; } case SDLK_PAGEUP: { CRect ClientRect(GetClientRect()); int nItemsPerPage = ClientRect.Height() / m_iItemHeight; if (m_iFocusedItem - nItemsPerPage > 0) { m_iFocusedItem -= nItemsPerPage; } else { m_iFocusedItem = 0; } m_pVScrollbar->SetPosition(m_iFocusedItem); StartDrawProc(); bHandled=true; break; } case SDLK_SPACE: { if (! m_Items.empty()) { SetSelection(m_iFocusedItem, !IsSelected(m_iFocusedItem)); StartDrawProc(); } bHandled = true; break; } default: { bHandled=false; break; } } } break; } case CMessage::CTRL_VALUECHANGE: case CMessage::CTRL_VALUECHANGING: { if (pMessage->Source() == m_pVScrollbar) { StartDrawProc(); bHandled = true; } break; } default : bHandled = CWindow::HandleMessage(pMessage); break; } } return bHandled;}}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -