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

📄 wm.c

📁 MCB2300_ucgui_LCD320240.rar LPC2368的uc/gui的移植
💻 C
📖 第 1 页 / 共 4 页
字号:
	if ((pWin->cb != NULL) && (Status & WM_SF_ISVIS))
	{
		WM_MESSAGE Msg;
		WM__PaintCallbackCnt++;
		if (Status & WM_SF_LATE_CLIP)
		{
			Msg.hWin = hWin;
			Msg.MsgId = WM_PAINT;
			Msg.Data.p = (GUI_RECT *) &pWin->InvalidRect;
			WM_SetDefault();
			WM_SendMessage(hWin, &Msg);
		}
		else
		{
			WM_ITERATE_START(&pWin->InvalidRect)
			{
				Msg.hWin = hWin;
				Msg.MsgId = WM_PAINT;
				Msg.Data.p = (GUI_RECT *) &pWin->InvalidRect;
				WM_SetDefault();
				WM_SendMessage(hWin, &Msg);
			} WM_ITERATE_END();
		}
		WM__PaintCallbackCnt--;
	}
}
/*********************************************************************
*
*   	_Paint1Trans
*
* Purpose:
*   Draw a transparent window as part of an other one (the active window: pAWin).
*   This is required because transparent windows are drawn as part of their
*   non-transparent parents.
* Return value:
*   0 if nothing was drawn (no invalid rect)
*   1 if something was drawn (invalid rect exists)
* Add. info:
*   It is important to restore the modified settings, especially the invalid rectangle
*   of the window. The invalid rectangle needs to be set, as it is passed as add. info
*   to the callback on WM_PAINT.
*   On traditional transparent windows, the transparent window is never drawn on its own,
*   so there is no need to restore the invalid rectangle.
*   However, with WM_SF_CONST_OUTLINE, the window itself may need to be redrawn because it
*   can be invalid. Modifying the invalid rectangle would lead to not updating the window
*   in the worst case.
*/

#if WM_SUPPORT_TRANSPARENCY
static int _Paint1Trans(WM_HWIN hWin, WM_Obj *pWin)
{
	int xPrev, yPrev;
	WM_Obj* pAWin = WM_H2P(GUI_Context.hAWin);
	/* Check if we need to do any drawing */
	if (GUI_RectsIntersect(&pAWin->InvalidRect, &pWin->Rect))
	{
		/* Save old values */
		xPrev = GUI_Context.xOff;
		yPrev = GUI_Context.yOff;
		/* Set values for the current (transparent) window, rather than the one below */
		GUI__IntersectRects(&pWin->InvalidRect, &pWin->Rect, &pAWin->InvalidRect);
		WM__hATransWindow = hWin;
		GUI_Context.xOff = pWin->Rect.x0;
		GUI_Context.yOff = pWin->Rect.y0;
		/* Do the actual drawing ... */
		_Paint1(hWin, pWin);
		/* Restore settings */
		WM__hATransWindow = 0;
		GUI_Context.xOff = xPrev;
		GUI_Context.yOff = yPrev;
		return 1;   					/* Some drawing took place */
	}
	return 0;   					  /* No invalid area, so nothing was drawn */
}
#endif

/*********************************************************************
*
*   	_PaintTransChildren
*
* Purpose:
*   Paint transparent children. This function is obviously required
*   only if there are transparent windows.
* Function:  Obvious
* Parameter: Obvious
* Returns:   ---
*/
#if WM_SUPPORT_TRANSPARENCY
static void _PaintTransChildren(WM_Obj *pWin)
{
	WM_HWIN hChild;
	WM_Obj* pChild;
	if (pWin->Status & WM_SF_ISVIS)
	{
		for (hChild = pWin->hFirstChild; hChild; hChild = pChild->hNext)
		{
			pChild = WM_H2P(hChild);
			if ((pChild->Status & (WM_SF_HASTRANS | WM_SF_ISVIS))   /* Transparent & visible ? */ == (WM_SF_HASTRANS | WM_SF_ISVIS))
			{
				/* Set invalid area of the window to draw */
				if (GUI_RectsIntersect(&pChild->Rect, &pWin->InvalidRect))
				{
					GUI_RECT InvalidRectPrev;
					InvalidRectPrev = pWin->InvalidRect;
					if (_Paint1Trans(hChild, pChild))
					{
						_PaintTransChildren(pChild);
					}
					pWin->InvalidRect = InvalidRectPrev;
				}
			}
		}
	}
}
#endif

/*********************************************************************
*
*   	_PaintTransTopSiblings
*
* Purpose:
*   Paint transparent top siblings. This function is obviously required
*   only if there are transparent windows.
* Function:  Obvious
* Parameter: Obvious
* Returns:   ---
*/
#if WM_SUPPORT_TRANSPARENCY
static void _PaintTransTopSiblings(WM_HWIN hWin, WM_Obj *pWin)
{
	WM_HWIN hParent;
	WM_Obj* pParent;
	hParent = pWin->hParent;
	hWin = pWin->hNext;
	while (hParent)
	{
		/* Go hierarchy up to desktop window */
		for (; hWin; hWin = pWin->hNext)
		{
			pWin = WM_H2P(hWin);
			/* paint window if it is transparent & visible */
			if ((pWin->Status & (WM_SF_HASTRANS | WM_SF_ISVIS)) == (WM_SF_HASTRANS | WM_SF_ISVIS))
			{
				_Paint1Trans(hWin, pWin);
			}
			/* paint transparent & visible children */
			_PaintTransChildren(pWin);
		}
		pParent = WM_H2P(hParent);
		hWin = pParent->hNext;
		hParent = pParent->hParent;
	}
}
#endif

/*********************************************************************
*
*   	Callback for Paint message
*
* This callback is used by the window manger in conjunction with
* banding memory devices. A pointer to this routine is given to
* the banding memory device. This callback in turn will send the
* paint message to the window.
*
**********************************************************************
*/

/*********************************************************************
*
*   	WM__PaintWinAndOverlays
*
* Purpose
*   Paint the given window and all overlaying windows
*   (transparent children and transparent top siblings)
*/
void WM__PaintWinAndOverlays(WM_PAINTINFO *pInfo)
{
	WM_HWIN hWin;
	WM_Obj* pWin;
	hWin = pInfo->hWin;
	pWin = pInfo->pWin;
#if WM_SUPPORT_TRANSPARENCY
	/* Transparent windows without const outline are drawn as part of the background and can be skipped. */
	if ((pWin->Status & (WM_SF_HASTRANS | WM_SF_CONST_OUTLINE)) != WM_SF_HASTRANS)
	{
#endif
		_Paint1(hWin, pWin);	/* Draw the window itself */
#if WM_SUPPORT_TRANSPARENCY
	}
	if (WM__TransWindowCnt != 0)
	{
		_PaintTransChildren(pWin);  	 /* Draw all transparent children */
		_PaintTransTopSiblings(hWin, pWin);    /* Draw all transparent top level siblings */
	}
#endif
}

/*********************************************************************
*
*   	_cbPaintMemDev
*
* Purpose:
*   This is the routine called by the banding memory device. It calls
*   the same _cbPaint Routine which is also used when drawing directly;
*   the only add. work done is adjustment of the invalid rectangle.
*   This way the invalid rectangle visible by the window callback function
*   is limited to the current band, allowing the callback to optimize
*   better.
*/
#if GUI_SUPPORT_MEMDEV
static void _cbPaintMemDev(void *p)
{
	GUI_RECT Rect;
	WM_Obj* pWin = WM_H2P(GUI_Context.hAWin);
	Rect = pWin->InvalidRect;
	pWin->InvalidRect = GUI_Context.ClipRect;
	WM__PaintWinAndOverlays((WM_PAINTINFO *) p);
	pWin->InvalidRect = Rect;
}
#endif

/*********************************************************************
*
*   	_Paint
  Returns:
	1: a window has been redrawn
	0: No window has been drawn  
*/
static int _Paint(WM_HWIN hWin, WM_Obj *pWin)
{
	int Ret = 0;
	if (pWin->Status & WM_SF_INVALID)
	{
		if (pWin->cb)
		{
			if (WM__ClipAtParentBorders(&pWin->InvalidRect, hWin))
			{
				WM_PAINTINFO Info;
				Info.hWin = hWin;
				Info.pWin = pWin;
				WM_SelectWindow(hWin);
#if GUI_SUPPORT_MEMDEV
				if (pWin->Status & WM_SF_MEMDEV)
				{
					int Flags;
					GUI_RECT r = pWin->InvalidRect;
					Flags = (pWin->Status & WM_SF_HASTRANS) ? GUI_MEMDEV_HASTRANS : GUI_MEMDEV_NOTRANS;
					/*
					 * Currently we treat a desktop window as transparent, because per default it does not repaint itself.
					 */
					if (pWin->hParent == 0)
					{
						Flags = GUI_MEMDEV_HASTRANS;
					}
					GUI_MEMDEV_Draw(&r, _cbPaintMemDev, &Info, 0, Flags);
				}
				else
						#endif
				{
					WM__PaintWinAndOverlays(&Info);
					Ret = 1;	/* Something has been done */
				}
			}
		}
		/* We purposly clear the invalid flag after painting so we can still query the invalid rectangle while painting */
		pWin->Status &= ~WM_SF_INVALID; /* Clear invalid flag */
		if (pWin->Status & WM_CF_MEMDEV_ON_REDRAW)
		{
			pWin->Status |= WM_CF_MEMDEV;
		}
		WM__NumInvalidWindows--;
	}
	return Ret; 	 /* Nothing done */
}

/*********************************************************************
*
*   	_DrawNext
*/
static void _DrawNext(void)
{
	int UpdateRem = 1;
	WM_HWIN iWin = (NextDrawWin == WM_HWIN_NULL) ? WM__FirstWin : NextDrawWin;
	GUI_CONTEXT ContextOld;
	GUI_SaveContext(&ContextOld);
	/* Make sure the next window to redraw is valid */
	for (; iWin && UpdateRem;)
	{
		WM_Obj* pWin = WM_H2P(iWin);
		if (_Paint(iWin, pWin))
		{
			UpdateRem--;  /* Only the given number of windows at a time ... */
		}
		iWin = pWin->hNextLin;
	}  
	NextDrawWin = iWin;   /* Remember the window */
	GUI_RestoreContext(&ContextOld);
}

/*********************************************************************
*
*   	WM_Exec1
*/
int WM_Exec1(void)
{
	/* Poll PID if necessary */
	if (WM_pfPollPID)
	{
		WM_pfPollPID();
	}
	if (WM_pfHandlePID)
	{
		if (WM_pfHandlePID())
		{
			return 1;
		}   			/* We have done something ... */
	}
	if (GUI_PollKeyMsg())
	{
		return 1;   			/* We have done something ... */
	}
	if (WM_IsActive && WM__NumInvalidWindows)
	{
		WM_LOCK();
		_DrawNext();
		WM_UNLOCK();
		return 1;   			/* We have done something ... */
	}
	return 0;   			   /* There was nothing to do ... */
}

/*********************************************************************
*
*   	WM_Exec
*/
int WM_Exec(void)
{
	int r = 0;
	while (WM_Exec1())
	{
		r = 1;  				/* We have done something */
	}
	return r;
}

/*********************************************************************
*
*   	cbBackWin
*
* Purpose
*   Callback for background window
*
*/
static void cbBackWin(WM_MESSAGE *pMsg)
{
	const WM_KEY_INFO* pKeyInfo;
	switch (pMsg->MsgId)
	{
		case WM_KEY:
			pKeyInfo = (const WM_KEY_INFO *) pMsg->Data.p;
			if (pKeyInfo->PressedCnt == 1)
			{
				GUI_StoreKey(pKeyInfo->Key);
			}
			break;
		case WM_PAINT:
			{
				int LayerIndex;
#if GUI_NUM_LAYERS > 1
				LayerIndex = _DesktopHandle2Index(pMsg->hWin);
#else
				LayerIndex = 0;
#endif
				if (WM__aBkColor[LayerIndex] != GUI_INVALID_COLOR)
				{
					GUI_SetBkColor(WM__aBkColor[LayerIndex]);
					GUI_Clear();
				}
			}
		default:
			WM_DefaultProc(pMsg);
	}
}

/*********************************************************************
*
*   	WM_Activate
*/
void WM_Activate(void)
{
	WM_IsActive = 1;	   /* Running */
}

/*********************************************************************
*
*   	WM_Deactivate
*/
void WM_Deactivate(void)
{
	WM_IsActive = 0;	   /* No clipping performed by WM */
	WM_LOCK();
	LCD_SetClipRectMax();
	WM_UNLOCK();
}

/*********************************************************************
*
*   	WM_DefaultProc
*
* Purpose
*   Default callback for windows
*   Any window should call this routine in the "default" part of the
*   its callback function for messages it does not handle itself.
*
*/
void WM_DefaultProc(WM_MESSAGE *pMsg)
{
	WM_HWIN hWin = pMsg->hWin;
	const void *p = pMsg->Data.p;
	WM_Obj* pWin = WM_H2P(hWin);
	/* Exec message */
	switch (pMsg->MsgId)
	{
		case WM_GET_INSIDE_RECT:
			/* return client window in absolute (screen) coordinates */
			WM__GetClientRectWin(pWin, (GUI_RECT *) p);
			break;
		case WM_GET_CLIENT_WINDOW:
			/* return handle to client window. For most windows, there is no seperate client window, so it is the same handle */
			pMsg->Data.v = (int) hWin;
			return; 					  /* Message handled */
		case WM_KEY:
			WM_SendToParent(hWin, pMsg);
			return; 					  /* Message handled */
		case WM_GET_BKCOLOR:
			pMsg->Data.Color = GUI_INVALID_COLOR;
			return; 					  /* Message handled */
		case WM_NOTIFY_ENABLE:
			WM_InvalidateWindow(hWin);    
			return; 					  /* Message handled */
	}
	/* Message not handled. If it queries something, we return 0 to be on the safe side. */
	pMsg->Data.v = 0;
	pMsg->Data.p = 0;
}

/*********************************************************************
*
*   	WM_Init
*/
void WM_Init(void)
{
	if (!_IsInited)
	{
		NextDrawWin = WM__FirstWin = WM_HWIN_NULL;
		GUI_Context.WM__pUserClipRect = NULL;
		WM__NumWindows = WM__NumInvalidWindows = 0;
		/* Make sure we have at least one window. This greatly simplifies the
			  drawing routines as they do not have to check if the window is valid.
		  */
#if GUI_NUM_LAYERS == 1
		WM__ahDesktopWin[0] = WM_CreateWindow(0, 0, GUI_XMAX, GUI_YMAX, WM_CF_SHOW, cbBackWin, 0);
		WM__aBkColor[0] = GUI_INVALID_COLOR;
		WM_InvalidateWindow(WM__ahDesktopWin[0]); /* Required because a desktop window has no parent. */
#else
		{
			int i;
			for (i = 0; i < GUI_NUM_LAYERS; i++)
			{
				WM__ahDesktopWin[i] = WM_CreateWindowAsChild(0, 0, GUI_XMAX, GUI_YMAX, WM_UNATTACHED, WM_CF_SHOW, cbBackWin, 0);
				WM__aBkColor[i] = GUI_INVALID_COLOR;
				WM_InvalidateWindow(WM__ahDesktopWin[i]); /* Required because a desktop window has no parent. */
			}
		}
#endif
		/* Register the critical handles ... Note: This could be moved into the module setting the Window handle */
		WM__AddCriticalHandle(&WM__CHWinModal);
		WM__AddCriticalHandle(&WM__CHWinLast);

		WM_SelectWindow(WM__ahDesktopWin[0]);
		WM_Activate();
		_IsInited = 1;
	}
}


#else
void WM(void)
{
} /* avoid empty object files */
#endif   /* GUI_WINSUPPORT */

/*************************** End of file ****************************/

⌨️ 快捷键说明

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