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

📄 wg_menu.cpp

📁 一个小巧的嵌入式图形系统wGUI, 可以用VC编译
💻 CPP
📖 第 1 页 / 共 2 页
字号:
				iWidth += 9;			}			else			{				CPoint Dims;				iter->second.first.GetMetrics(&Dims, 0, 0);				CRect TextRect(SubRect.Left() + iWidth, SubRect.Top() + 2, SubRect.Left() + iWidth + Dims.XPos(), SubRect.Bottom() - 2);				TextRect.Grow(2);				iter->second.second = TextRect;				iWidth += Dims.XPos() + 8;			}		}		m_bCachedRectsValid = true;	}}void CMenu::ShowActivePopup(const CRect& ParentRect, const CRect& BoundingRect){	// TODO: Add bounds checking for all edges.	Apply this same bounds checking logic to the popup root menu too.	if (!m_pActivePopup)	{		throw(Wg_Ex_App("CMenu::ShowActivePopup() : Trying to show active popup menu when pActivePopup is NULL!"));	}	CRect MenuRect = m_pActivePopup->GetWindowRect();	if (BoundingRect.HitTest(ParentRect.BottomLeft() + CPoint(MenuRect.Width(), 0)) & CRect::RELPOS_RIGHT)	{		int xDelta = BoundingRect.Right() - ParentRect.Left() + MenuRect.Width();		if (!(BoundingRect.HitTest(ParentRect.BottomLeft() + CPoint(xDelta, 0)) & CRect::RELPOS_LEFT))		{			m_pActivePopup->Show(ParentRect.BottomLeft() + CPoint(xDelta, 5));		}	}	else	{		m_pActivePopup->Show(ParentRect.BottomLeft() + CPoint(0, 5));	}	// Pop the popup to the top of the draw order and everything	m_pActivePopup->SetNewParent(m_pActivePopup->GetAncestor(PARENT));}// CPopupMenuCPopupMenu::CPopupMenu(const CRect& WindowRect, CWindow* pParent, CFontEngine* pFontEngine) :	CMenuBase(WindowRect, pParent, pFontEngine),	m_pParentMenu(0){  m_sClassName = "CPopupMenu";	m_bVisible = false;	CMessageServer::Instance().RegisterMessageClient(this, CMessage::MOUSE_BUTTONDOWN);}CPopupMenu::~CPopupMenu(void){}void CPopupMenu::Show(CPoint Position){	if (m_bVisible)	{		Hide();	}	int iHeight = 4;	for (t_MenuItemVector::iterator iter = m_MenuItems.begin(); iter != m_MenuItems.end(); ++iter)	{		if (iter->first.bSpacer)			iHeight += 6;		else		{			CPoint Dims;			iter->second.first.GetMetrics(&Dims, 0, 0);			iHeight += Dims.YPos() + 5;		}	}	SetWindowRect(CRect(Position, Position + CPoint(m_WindowRect.Width() - 1, iHeight + 2)));	m_bVisible = true;	StartDrawProc();}void CPopupMenu::Hide(void){	HideActivePopup();	m_bVisible = false;	m_bCachedRectsValid = false;	CMessageServer::Instance().QueueMessage(new CMessage(CMessage::APP_PAINT, 0, this));	m_pHighlightedItem = 0;}void CPopupMenu::HideAll(void){	CPopupMenu* pParentPopup = dynamic_cast<CPopupMenu*>(m_pParentWindow);	if (pParentPopup)	{		pParentPopup->HideAll();	}	else	{		CMenu* pRootMenu = dynamic_cast<CMenu*>(m_pParentWindow);		if (pRootMenu)		{			pRootMenu->HideActivePopup();		}		else		{			Hide();		}	}}bool CPopupMenu::IsInsideChild(CPoint& Point){	if (m_WindowRect.HitTest(Point) == CRect::RELPOS_INSIDE)	{		return true;	}	if (!m_pActivePopup)	{		return false;	}	return m_pActivePopup->IsInsideChild(Point);}void CPopupMenu::Draw(void) const{	CWindow::Draw();	CPainter Painter(m_pSDLSurface);	Painter.DrawRect(m_WindowRect, false, COLOR_LIGHTGRAY);	Painter.DrawHLine(m_WindowRect.Left(), m_WindowRect.Right(), m_WindowRect.Bottom(), COLOR_DARKGRAY);	Painter.DrawVLine(m_WindowRect.Top(), m_WindowRect.Bottom(), m_WindowRect.Right(), COLOR_DARKGRAY);	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.DrawHLine(TextRect.Left(), TextRect.Right(), TextRect.Top(), COLOR_LIGHTGRAY);			Painter.DrawHLine(TextRect.Left(), TextRect.Right(), TextRect.Bottom(), COLOR_DARKGRAY);		}		else			iter->second.first.Draw(m_pSDLSurface, TextRect, TextRect.TopLeft());		if (iter->first.pPopup)		{			CRect ArrowRect(iter->second.second);			ArrowRect.SetLeft(ArrowRect.Right() - m_hRightArrowBitmap.Bitmap()->w);			SDL_Rect SourceRect;			SourceRect.x = static_cast<short int>(0);			SourceRect.y = static_cast<short int>((m_hRightArrowBitmap.Bitmap()->h - ArrowRect.Height()) / 2 < 0 ?				0 : (m_hRightArrowBitmap.Bitmap()->h - ArrowRect.Height()) / 2);			SourceRect.w = static_cast<short int>(m_hRightArrowBitmap.Bitmap()->w);			SourceRect.h = static_cast<short int>(std::min(ArrowRect.Height(), m_hRightArrowBitmap.Bitmap()->h));			SDL_Rect DestRect;			DestRect.x = static_cast<short int>(ArrowRect.Left());			DestRect.y = static_cast<short int>((ArrowRect.Height() - m_hRightArrowBitmap.Bitmap()->h) / 2 < 0 ?				ArrowRect.Top() : ArrowRect.Top() + (ArrowRect.Height() - m_hRightArrowBitmap.Bitmap()->h) / 2);			DestRect.w = static_cast<short int>(m_hRightArrowBitmap.Bitmap()->w);			DestRect.h = static_cast<short int>(std::min(ArrowRect.Height(), m_hRightArrowBitmap.Bitmap()->h));			SDL_BlitSurface(m_hRightArrowBitmap.Bitmap(), &SourceRect, m_pSDLSurface, &DestRect);		}	}}bool CPopupMenu::OnMouseButtonDown(CPoint Point, unsigned int Button){	bool bResult = false; 	if (! CMenuBase::OnMouseButtonDown(Point, Button) && m_bVisible && (m_WindowRect.HitTest(Point) == CRect::RELPOS_INSIDE))	{		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)			{				if (!iter->first.pPopup)				{					CMessageClient* pDestination = m_pParentWindow;					if (m_pParentMenu)					{						pDestination = m_pParentMenu;					}					CMessageServer::Instance().QueueMessage(new TIntMessage(CMessage::CTRL_LCLICK, pDestination, this, iter->first.iItemId));					HideAll();				}				else				{					HideActivePopup();					m_pActivePopup = iter->first.pPopup;					ShowActivePopup(iter->second.second, GetAncestor(ROOT)->GetClientRect());				}				break;			}		}		bResult = true;	}	return bResult;}bool CPopupMenu::HandleMessage(CMessage* pMessage){	bool bHandled = false;	if (pMessage)	{		switch(pMessage->MessageType())		{		case CMessage::MOUSE_BUTTONDOWN:		{			CMouseMessage* pMouseMessage = dynamic_cast<CMouseMessage*>(pMessage);			if (m_bVisible && pMouseMessage && (m_WindowRect.HitTest(pMouseMessage->Point) != CRect::RELPOS_INSIDE))			{				// If the user clicked outside the window, we just want to hide the window,				// and then pass the message on (bHandled = false)				// But we only want the root popup to do this, and only if none of it's children were hit				if (!dynamic_cast<CPopupMenu*>(m_pParentWindow) && !IsInsideChild(pMouseMessage->Point) &&					!(m_pParentMenu && m_pParentMenu->GetWindowRect().HitTest(pMouseMessage->Point) == CRect::RELPOS_INSIDE))				{					HideAll();				}			}			break;		}		case CMessage::CTRL_TIMER:		{			if (pMessage->Destination() == this)			{				CRect ItemRect;				for (t_MenuItemVector::iterator iter = m_MenuItems.begin(); iter != m_MenuItems.end(); ++iter)				{					if (m_pHighlightedItem == &(iter->first))					{						ItemRect = iter->second.second;						break;					}				}				if (m_pHighlightedItem && m_pHighlightedItem->pPopup)				{					HideActivePopup();					m_pActivePopup = m_pHighlightedItem->pPopup;					ShowActivePopup(ItemRect, GetAncestor(ROOT)->GetClientRect());				}				bHandled = true;			}			break;		}		default :			bHandled = CMenuBase::HandleMessage(pMessage);			break;		}	}	return bHandled;}void CPopupMenu::UpdateCachedRects(void) const{	if (!m_bCachedRectsValid)	{		CRect SubRect(m_WindowRect);		SubRect.Grow(-2);		int iHeight = 4;		for (t_MenuItemVector::iterator iter = m_MenuItems.begin(); iter != m_MenuItems.end(); ++iter)		{			if (iter->first.bSpacer)			{				CRect TextRect(SubRect.Left() + 3, SubRect.Top() + iHeight, SubRect.Right() - 3, SubRect.Top() + iHeight + 1);				TextRect.Grow(2);				iter->second.second = TextRect;				iHeight += 6;			}			else			{				CPoint Dims;				iter->second.first.GetMetrics(&Dims, 0, 0);				CRect TextRect(SubRect.Left() + 3, SubRect.Top() + iHeight, SubRect.Right() - 3, SubRect.Top() + iHeight + Dims.YPos());				TextRect.Grow(2);				iter->second.second = TextRect;				iHeight += Dims.YPos() + 5;			}		}		m_bCachedRectsValid = true;	}}void CPopupMenu::ShowActivePopup(const CRect& ParentRect, const CRect& BoundingRect){	// TODO: Add bounds checking for all edges.	Apply this same bounds checking logic to the popup root menu too.	if (!m_pActivePopup)	{		throw(Wg_Ex_App("CPopupMenu::ShowActivePopup() : Trying to show active popup menu when pActivePopup is NULL!"));	}	CRect MenuRect = m_pActivePopup->GetWindowRect();	if (BoundingRect.HitTest(ParentRect.TopRight() + CPoint(5, 0) + CPoint(MenuRect.Width(), 0)) & CRect::RELPOS_RIGHT)	{		m_pActivePopup->Show(ParentRect.TopLeft() - CPoint(MenuRect.Width() + 5, 0));	}	else	{		m_pActivePopup->Show(ParentRect.TopRight() + CPoint(5, 0));	}}}

⌨️ 快捷键说明

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