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

📄 wg_menu.cpp

📁 一个小巧的嵌入式图形系统wGUI, 可以用VC编译
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// wg_menu.cpp//// CMenu 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_menu.h"#include "std_ex.h"#include "wg_application.h"#include "wg_message_server.h"#include "wg_debug.h"#include "wg_error.h"namespace wGui{// CMenuBaseCMenuBase::CMenuBase(const CRect& WindowRect, CWindow* pParent, CFontEngine* pFontEngine) :	CWindow(WindowRect, pParent),	m_pHighlightedItem(0),	m_bCachedRectsValid(false),	m_pActivePopup(0),	m_hRightArrowBitmap(WGRES_RIGHT_ARROW_BITMAP),	m_HighlightColor(COLOR_DARKGRAY){  m_sClassName = "CMenuBase";	if (pFontEngine)	{		m_pFontEngine = pFontEngine;	}	else	{		m_pFontEngine = CApplication::Instance()->GetDefaultFontEngine();	}	CMessageServer::Instance().RegisterMessageClient(this, CMessage::MOUSE_MOVE);	CMessageServer::Instance().RegisterMessageClient(this, CMessage::CTRL_LCLICK);	CMessageServer::Instance().RegisterMessageClient(this, CMessage::CTRL_TIMER);	m_pPopupTimer = new CTimer(this);}CMenuBase::~CMenuBase(void){}void CMenuBase::InsertMenuItem(const SMenuItem& MenuItem, int iPosition){	m_MenuItems.insert((iPosition == -1) ? m_MenuItems.end() : m_MenuItems.begin() + iPosition,		std::make_pair(MenuItem, std::make_pair(CRenderedString(m_pFontEngine, MenuItem.sItemText, CRenderedString::VALIGN_TOP), CRect())));	m_bCachedRectsValid = false;}void CMenuBase::RemoveMenuItem(int iPosition){	m_MenuItems.erase(m_MenuItems.begin() + iPosition);	m_bCachedRectsValid = false;	StartDrawProc();}void CMenuBase::HideActivePopup(void){	if (m_pActivePopup)	{		m_pActivePopup->Hide();		m_pActivePopup = 0;	}}bool CMenuBase::OnMouseButtonDown(CPoint Point, unsigned int Button){	// We cant do quite the same thing as normal since children of menus don't appear inside their bounds	bool bResult = false;	if (m_bVisible)	{		for (std::list<CWindow*>::reverse_iterator iter = m_ChildWindows.rbegin(); iter != m_ChildWindows.rend(); ++iter)		{			bResult = (*iter)->OnMouseButtonDown(Point, Button);			if (bResult)			{				break;			}		}	}	return bResult;}bool CMenuBase::HandleMessage(CMessage* pMessage){	bool bHandled = false;	if (pMessage)	{		switch(pMessage->MessageType())		{		case CMessage::MOUSE_MOVE:		{			CMouseMessage* pMouseMessage = dynamic_cast<CMouseMessage*>(pMessage);			if (m_bVisible && pMouseMessage && m_WindowRect.HitTest(pMouseMessage->Point) == CRect::RELPOS_INSIDE)			{				UpdateCachedRects();				SMenuItem* pOldHighlight = m_pHighlightedItem;				m_pHighlightedItem = 0;				for (t_MenuItemVector::iterator iter = m_MenuItems.begin(); iter != m_MenuItems.end(); ++iter)				{					if (iter->second.second.HitTest(pMouseMessage->Point) == CRect::RELPOS_INSIDE && !iter->first.bSpacer)					{						if (m_pHighlightedItem != &(iter->first))						{							m_pPopupTimer->StopTimer();							m_pHighlightedItem = &(iter->first);							if (iter->first.pPopup)							{								m_pPopupTimer->StartTimer(1000);							}						}						break;					}				}				if (pOldHighlight != m_pHighlightedItem)				{					TraceIf(m_pHighlightedItem != 0, "Menu Highlight Item Changed to : " + (m_pHighlightedItem ? m_pHighlightedItem->sItemText : std::string("")));					StartDrawProc();				}			}			else if (m_pHighlightedItem != 0)			{				m_pPopupTimer->StopTimer();				m_pHighlightedItem = 0;				StartDrawProc();			}			break;		}		case CMessage::CTRL_LCLICK:		{			TIntMessage* pCtrlMessage = dynamic_cast<TIntMessage*>(pMessage);			if (pCtrlMessage && pCtrlMessage->Destination() == this)			{				for (t_MenuItemVector::iterator iter = m_MenuItems.begin(); iter != m_MenuItems.end(); ++iter)				{					if (pCtrlMessage->Source() == iter->first.pPopup)					{						CMessageServer::Instance().QueueMessage(new TIntMessage(CMessage::CTRL_LCLICK, m_pParentWindow,							this, pCtrlMessage->Value()));						bHandled = true;						break;					}				}			}			break;		}		case CMessage::CTRL_TIMER:		{			if (pMessage->Destination() == this)			{				bHandled = true;			}			break;		}		default :			bHandled = CWindow::HandleMessage(pMessage);			break;		}	}	return bHandled;}// CMenuCMenu::CMenu(const CRect& WindowRect, CWindow* pParent, CFontEngine* pFontEngine) :	CMenuBase(WindowRect, pParent, pFontEngine){  m_sClassName = "CMenu";	CMessageServer::Instance().RegisterMessageClient(this, CMessage::MOUSE_MOVE);}CMenu::~CMenu(void){}void CMenu::InsertMenuItem(const SMenuItem& MenuItem, int iPosition){	m_MenuItems.insert((iPosition == -1) ? m_MenuItems.end() : m_MenuItems.begin() + iPosition,		std::make_pair(MenuItem, std::make_pair(CRenderedString(m_pFontEngine, MenuItem.sItemText, CRenderedString::VALIGN_NORMAL), CRect())));	m_bCachedRectsValid = false;	if (MenuItem.pPopup)	{		MenuItem.pPopup->SetParentMenu(this);	}}void CMenu::Draw(void) const{	CWindow::Draw();	CPainter Painter(m_pSDLSurface);	UpdateCachedRects();	for (t_MenuItemVector::const_iterator iter = m_MenuItems.begin(); iter != m_MenuItems.end(); ++iter)	{		if (m_pHighlightedItem == &(iter->first))		{			Painter.DrawRect(iter->second.second, true, m_HighlightColor, m_HighlightColor);		}		CRect TextRect(iter->second.second);		TextRect.Grow(-2);		if (iter->first.bSpacer)		{			Painter.DrawVLine(TextRect.Top(), TextRect.Bottom(), TextRect.Left(), COLOR_LIGHTGRAY);			Painter.DrawVLine(TextRect.Top(), TextRect.Bottom(), TextRect.Right(), COLOR_DARKGRAY);		}		else			iter->second.first.Draw(m_pSDLSurface, TextRect, CPoint(TextRect.Left(), (TextRect.Top() + TextRect.Bottom()) * 3 / 4));	}}bool CMenu::OnMouseButtonDown(CPoint Point, unsigned int Button){	bool bResult = false; 	if (! CMenuBase::OnMouseButtonDown(Point, Button) && m_bVisible && (m_WindowRect.HitTest(Point) == CRect::RELPOS_INSIDE) &&		(Button == CMouseMessage::LEFT))	{		UpdateCachedRects();		for (t_MenuItemVector::iterator iter = m_MenuItems.begin(); iter != m_MenuItems.end(); ++iter)		{			if (iter->second.second.HitTest(Point) == CRect::RELPOS_INSIDE && !iter->first.bSpacer)			{				HideActivePopup();				if (iter->first.pPopup)				{					CPopupMenu* pPopup = dynamic_cast<CPopupMenu*>(iter->first.pPopup);					if (pPopup)					{						m_pActivePopup = pPopup;						ShowActivePopup(iter->second.second, GetAncestor(ROOT)->GetClientRect());					}				}				else				{					CMessageServer::Instance().QueueMessage(new TIntMessage(CMessage::CTRL_LCLICK, m_pParentWindow, this, iter->first.iItemId));				}				break;			}		}		bResult = true;	}	return bResult;}bool CMenu::HandleMessage(CMessage* pMessage){	bool bHandled = false;	if (pMessage)	{		switch(pMessage->MessageType())		{		case CMessage::MOUSE_MOVE:		{			break;		}		default :			bHandled = CMenuBase::HandleMessage(pMessage);			break;		}	}	return bHandled;}void CMenu::UpdateCachedRects(void) const{	if (!m_bCachedRectsValid)	{		CRect SubRect(m_WindowRect);		SubRect.Grow(-2);		int iWidth = 5;		for (t_MenuItemVector::iterator iter = m_MenuItems.begin(); iter != m_MenuItems.end(); ++iter)		{			if (iter->first.bSpacer)			{				CRect TextRect(SubRect.Left() + iWidth, SubRect.Top() + 2, SubRect.Left() + iWidth + 1, SubRect.Bottom() - 2);				TextRect.Grow(2);				iter->second.second = TextRect;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -