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

📄 menu.c

📁 MCB2300_ucgui_LCD320240.rar LPC2368的uc/gui的移植
💻 C
📖 第 1 页 / 共 3 页
字号:
		for (i = 0; i < (int) Index; i++)
		{
			yPos += _GetItemHeight(hObj, pObj, i);
		}
		*px = EffectSize;
		*py = EffectSize + yPos;
	}
	else
	{
		int xPos = 0;
		for (i = 0; i < (int) Index; i++)
		{
			xPos += _GetItemWidth(hObj, pObj, i);
		}
		*px = EffectSize + xPos;
		*py = EffectSize;
	}
}

/*********************************************************************
*
*   	_SetCapture
*/
static void _SetCapture(MENU_Handle hObj, const MENU_Obj *pObj)
{
	if (pObj->IsSubmenuActive == 0)
	{
		if (WM_HasCaptured(hObj) == 0)
		{
			WM_SetCapture(hObj, 0);
		}
	}
}

/*********************************************************************
*
*   	_ReleaseCapture
*/
static void _ReleaseCapture(MENU_Handle hObj, const MENU_Obj *pObj)
{
	if (WM_HasCaptured(hObj))
	{
		if (_IsTopLevelMenu(hObj, pObj) && !(pObj->Flags & MENU_SF_POPUP))
		{
			WM_ReleaseCapture();
		}
	}
}

/*********************************************************************
*
*   	_CloseSubmenu
*/
static void _CloseSubmenu(MENU_Handle hObj, MENU_Obj *pObj)
{
	if (pObj->Flags & MENU_SF_ACTIVE)
	{
		if (pObj->IsSubmenuActive)
		{
			MENU_ITEM* pItem = (MENU_ITEM *) GUI_ARRAY_GetpItem(&pObj->ItemArray, pObj->Sel);
			/* Inform submenu about its deactivation and detach it */
			MENU__SendMenuMessage(hObj, pItem->hSubmenu, MENU_ON_CLOSE, 0);
			WM_DetachWindow(pItem->hSubmenu);
			pObj->IsSubmenuActive = 0;
			/*
			 * Keep capture in menu widget. The capture may only released
			 * by clicking outside the menu or when mouse moved out.
			 * And it may only released from a top level menu.
			 */
			_SetCapture(hObj, pObj);
			/* Invalidate menu item. This is needed because the appearance may have changed */
			MENU__InvalidateItem(hObj, pObj, pObj->Sel);
		}
	}
}

/*********************************************************************
*
*   	_OpenSubmenu
*/
static void _OpenSubmenu(MENU_Handle hObj, MENU_Obj *pObj, unsigned Index)
{
	if (pObj->Flags & MENU_SF_ACTIVE)
	{
		MENU_ITEM* pItem;
		char PrevActiveSubmenu;
		PrevActiveSubmenu = pObj->IsSubmenuActive;
		/* Close previous submenu (if needed) */
		_CloseSubmenu(hObj, pObj);
		pItem = (MENU_ITEM *) GUI_ARRAY_GetpItem(&pObj->ItemArray, Index);
		if (pItem->hSubmenu)
		{
			if ((pItem->Flags & MENU_IF_DISABLED) == 0)
			{
				int x, y, EffectSize;
				/* Calculate position of submenu */
				EffectSize = _GetEffectSize(hObj, pObj);
				_GetItemPos(hObj, pObj, Index, &x, &y);
				if (pObj->Flags & MENU_SF_VERTICAL)
				{
					x += _CalcMenuSizeX(hObj, pObj) - (_GetEffectSize(hObj, pObj) << 1);
					y -= EffectSize;
				}
				else
				{
					y += _CalcMenuSizeY(hObj, pObj) - (_GetEffectSize(hObj, pObj) << 1);
					x -= EffectSize;
				}
				x += WM_GetWindowOrgX(hObj);
				y += WM_GetWindowOrgY(hObj);
				/*
				 * Notify owner window when for the first time open a menu (when no
				 * other submenu was open), so it can initialize the menu items.
				 */
				if (PrevActiveSubmenu == 0)
				{
					if (_IsTopLevelMenu(hObj, pObj))
					{
						MENU__SendMenuMessage(hObj, pObj->hOwner, MENU_ON_INITMENU, 0);
					}
				}
				/* Notify owner window when a submenu opens, so it can initialize the menu items. */
				MENU__SendMenuMessage(hObj, pObj->hOwner, MENU_ON_INITSUBMENU, pItem->Id);
				/* Set active menu as owner of submenu. */
				MENU_SetOwner(pItem->hSubmenu, hObj);
				/* Attach submenu and inform it about its activation. */
				WM_AttachWindowAt(pItem->hSubmenu, WM_HBKWIN, x, y);
				MENU__SendMenuMessage(hObj, pItem->hSubmenu, MENU_ON_OPEN, 0);
				pObj->IsSubmenuActive = 1;
				/* Invalidate menu item. This is needed because the appearance may have changed. */
				MENU__InvalidateItem(hObj, pObj, Index);
			}
		}
	}
}

/*********************************************************************
*
*   	_ClosePopup
*/
static void _ClosePopup(MENU_Handle hObj, MENU_Obj *pObj)
{
	if (pObj->Flags & MENU_SF_POPUP)
	{
		pObj->Flags &= ~(MENU_SF_POPUP);
		WM_DetachWindow(hObj);
		WM_ReleaseCapture();
	}
}

/*********************************************************************
*
*   	_SetSelection
*/
static void _SetSelection(MENU_Handle hObj, MENU_Obj *pObj, int Index)
{
	if (Index != pObj->Sel)
	{
		MENU__InvalidateItem(hObj, pObj, pObj->Sel); /* Invalidate previous selection */
		MENU__InvalidateItem(hObj, pObj, Index);	 /* Invalidate new selection */
		pObj->Sel = Index;
	}
}

/*********************************************************************
*
*   	_SelectItem
*/
static void _SelectItem(MENU_Handle hObj, MENU_Obj *pObj, unsigned Index)
{
	if (pObj->Sel != (int) Index)
	{
		_SetCapture(hObj, pObj);
		_OpenSubmenu(hObj, pObj, Index);
		_SetSelection(hObj, pObj, Index);
	}
}

/*********************************************************************
*
*   	_DeselectItem
*/
static void _DeselectItem(MENU_Handle hObj, MENU_Obj *pObj)
{
	if (pObj->IsSubmenuActive == 0)
	{
		_SetSelection(hObj, pObj, -1);
		_ReleaseCapture(hObj, pObj);
	}
}

/*********************************************************************
*
*   	_ActivateItem
*/
static void _ActivateItem(MENU_Handle hObj, MENU_Obj *pObj, unsigned Index)
{
	MENU_ITEM* pItem;
	pItem = (MENU_ITEM *) GUI_ARRAY_GetpItem(&pObj->ItemArray, Index);
	if (pItem->hSubmenu == 0)
	{
		if ((pItem->Flags & (MENU_IF_DISABLED | MENU_IF_SEPARATOR)) == 0)
		{
			_ClosePopup(hObj, pObj);
			/* Send item select message to owner. */
			MENU__SendMenuMessage(hObj, pObj->hOwner, MENU_ON_ITEMSELECT, pItem->Id);
		}
	}
}

/*********************************************************************
*
*   	_ActivateMenu
*/
static void _ActivateMenu(MENU_Handle hObj, MENU_Obj *pObj, unsigned Index)
{
	if ((pObj->Flags & MENU_SF_OPEN_ON_POINTEROVER) == 0)
	{
		MENU_ITEM* pItem;
		pItem = (MENU_ITEM *) GUI_ARRAY_GetpItem(&pObj->ItemArray, Index);
		if (pItem->hSubmenu)
		{
			if ((pItem->Flags & MENU_IF_DISABLED) == 0)
			{
				if ((pObj->Flags & MENU_SF_ACTIVE) == 0)
				{
					pObj->Flags |= MENU_SF_ACTIVE;
					_OpenSubmenu(hObj, pObj, Index);
					_SetSelection(hObj, pObj, Index);
				}
				else if (pObj->Flags & MENU_SF_CLOSE_ON_SECOND_CLICK)
				{
					if ((int) Index == pObj->Sel)
					{
						_CloseSubmenu(hObj, pObj);
						pObj->Flags &= ~MENU_SF_ACTIVE;
					}
				}
			}
		}
	}
}

/*********************************************************************
*
*   	_DeactivateMenu
*/
static void _DeactivateMenu(MENU_Handle hObj, MENU_Obj *pObj)
{
	_CloseSubmenu(hObj, pObj);
	if ((pObj->Flags & MENU_SF_OPEN_ON_POINTEROVER) == 0)
	{
		pObj->Flags &= ~MENU_SF_ACTIVE;
	}
}

/*******************************************************************
*
*   	_ForwardMouseOverMsg
*/
static int _ForwardMouseOverMsg(MENU_Handle hObj, MENU_Obj *pObj, int x, int y)
{
#if (GUI_SUPPORT_MOUSE)
	if ((pObj->IsSubmenuActive == 0) && !(pObj->Flags & MENU_SF_POPUP))
	{
		if (_IsTopLevelMenu(hObj, pObj))
		{
			WM_HWIN hBelow;
			x += WM_GetWindowOrgX(hObj);
			y += WM_GetWindowOrgY(hObj);
			hBelow = WM_Screen2hWin(x, y);
			if (hBelow && (hBelow != hObj))
			{
				WM_MESSAGE Msg;
				GUI_PID_STATE State;
				x -= WM_GetWindowOrgX(hBelow);
				y -= WM_GetWindowOrgY(hBelow);
				State.Pressed = 0;
				State.x = x;
				State.y = y;
				Msg.Data.p = &State;
				Msg.MsgId = WM_MOUSEOVER;
				WM__SendMessage(hBelow, &Msg);
				return 1;
			}
		}
	}
#endif
	return 0;
}

/*********************************************************************
*
*   	_HandlePID
*
* Return values:
*   1 = We need to forward PID message to owner.
*   0 = We do not need to inform owner.
*/
static char _HandlePID(MENU_Handle hObj, MENU_Obj *pObj, int x, int y, int Pressed)
{
	GUI_PID_STATE PrevState;
	char XYInWidget = 0;
	WM_PID__GetPrevState(&PrevState);
	/*
	 * Check if coordinates are inside the widget.
	 */
	if ((x >= 0) && (y >= 0))
	{
		GUI_RECT r;
		WM__GetClientRectWin(&pObj->Widget.Win, &r);
		if ((x <= r.x1) && (y <= r.y1))
		{
			XYInWidget = 1;
		}
	}

	if (XYInWidget)
	{
		int ItemIndex;
		ItemIndex = _GetItemFromPos(hObj, pObj, x, y);
		/* 
		 * Handle PID when coordinates are inside the widget.
		 */
		if (ItemIndex >= 0)
		{
			/* 
			 * Coordinates are inside the menu.
			 */
			if (Pressed == 1)
			{
				if (PrevState.Pressed == 0)
				{
					/* Clicked */
					_ActivateMenu(hObj, pObj, ItemIndex);
				}
				_SelectItem(hObj, pObj, ItemIndex);
			}
			else if ((Pressed == 0) && (PrevState.Pressed == 1))
			{
				/* Released */
				_ActivateItem(hObj, pObj, ItemIndex);
			}
			else if (Pressed < 0)
			{
				/* Mouse moved */
				if (_ForwardMouseOverMsg(hObj, pObj, x, y) == 0)
				{
					_SelectItem(hObj, pObj, ItemIndex);
				}
				else
				{
					_DeselectItem(hObj, pObj);
				}
			}
		}
		else
		{
			/* 
			 * Coordinates are outside the menu but inside the widget.
			 */
			if (Pressed == 1)
			{
				if (PrevState.Pressed == 0)
				{
					/* Clicked */
					/* 
					 * User has clicked outside the menu. Close the active submenu.
					 * The widget itself must be closed (if needed) by the owner.
					 */
					_DeactivateMenu(hObj, pObj);
				}
				_DeselectItem(hObj, pObj);
			}
			else if (Pressed < 0)
			{
				/* Moved out or mouse moved */
				_DeselectItem(hObj, pObj);
			}
		}
		return 0;
	}
	else
	{
		/* 
		 * Handle PID when coordinates are outside the widget.
		 */
		if ((Pressed == 1) && (PrevState.Pressed == 0))
		{
			/* 
			 * User has clicked outside the menu. Close the active submenu.
			 * The widget itself must be closed (if needed) by the owner.
			 */
			_DeactivateMenu(hObj, pObj);
			_ClosePopup(hObj, pObj);
		}
		_DeselectItem(hObj, pObj);
		_ForwardMouseOverMsg(hObj, pObj, x, y);
	}
	return 1;   /* Coordinates are not in widget, we need to forward PID message to owner */
}

/*********************************************************************
*
*   	_ForwardPIDMsgToOwner
*/
static void _ForwardPIDMsgToOwner(MENU_Handle hObj, MENU_Obj *pObj, WM_MESSAGE *pMsg)
{
	if (_IsTopLevelMenu(hObj, pObj) == 0)
	{
		WM_HWIN hOwner;
		hOwner = pObj->hOwner ? pObj->hOwner : WM_GetParent(hObj);
		if (hOwner)
		{
			if (pMsg->Data.p)
			{
				GUI_PID_STATE* pState;
				pState = (GUI_PID_STATE *) pMsg->Data.p;
				pState->x += WM_GetWindowOrgX(hObj) - WM_GetWindowOrgX(hOwner);
				pState->y += WM_GetWindowOrgY(hObj) - WM_GetWindowOrgY(hOwner);
			}
			WM__SendMessage(hOwner, pMsg);
		}
	}
}

/*********************************************************************
*
*   	Static routines, callback
*
**********************************************************************
*/
/*********************************************************************
*
*   	_OnMenu
*/
static void _OnMenu(MENU_Handle hObj, MENU_Obj *pObj, WM_MESSAGE *pMsg)
{
	const MENU_MSG_DATA* pData = (const MENU_MSG_DATA *) pMsg->Data.p;
	if (pData)
	{
		switch (pData->MsgType)
		{
			case MENU_ON_ITEMSELECT:
				_DeactivateMenu(hObj, pObj);
				_DeselectItem(hObj, pObj);
				_ClosePopup(hObj, pObj);
				/* No break here. We need to forward message to owner. */
			case MENU_ON_INITMENU:
			case MENU_ON_INITSUBMENU:
				/* Forward message to owner. */
				{
					WM_HWIN hOwner;
					hOwner = pObj->hOwner ? pObj->hOwner : WM_GetParent(hObj);
					if (hOwner)
					{
						pMsg->hWinSrc = hObj;
						WM__SendMessage(hOwner, pMsg);
					}
				}
				break;
			case MENU_ON_OPEN:

⌨️ 快捷键说明

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