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

📄 wnd.cpp

📁 基于ARM平台的控制系统,自己带有MINIGUI,可以直接在VC下运行界面演示程序
💻 CPP
字号:
#include "GUIpp.h"
#include "Glib.h"
#include "Wnd.h"

#if _USE_GUI == 1

NANADeskTopWnd *g_pDeskTopWnd;
void NANAGUI_Init(void)
{
	g_pDeskTopWnd = new NANADeskTopWnd;
}
/////////////////////////////////////////////////////////
int NANARect::GetWidth(void)
{
    return w_nX2-w_nX1;
}
int NANARect::GetHeight(void)
{
    return w_nY2-w_nY1;
}

void NANARect::MoveTo(int nX,int nY)
{
    int nWidth = GetWidth();
    int nHeight = GetHeight();
    
    w_nX1 = nX;
    w_nY1 = nY;
    w_nX2 = w_nX1 + nWidth;
    w_nY2 = w_nY1 + nHeight;
}

void NANARect::MoveBy(int nX,int nY)
{
    w_nX1 += nX;
    w_nY1 += nY;
    w_nX2 += nX;
    w_nY2 += nY;
}
int NANARect::IsPointInside(int x,int y)
{
    return (x>=w_nX1 && x<w_nX2 && y>=w_nY1 && y<w_nY2);
}

/////////////////////////////////////////////////////////

NANADeskTopWnd::NANADeskTopWnd():w_DeskTopTimer(this)
{
    w_Rect.w_nX1 = 0;
    w_Rect.w_nX2 = SCREEN_WIDTH;
    w_Rect.w_nY1 = 0;
    w_Rect.w_nY2 = SCREEN_HEIGHT;
    
    w_nStyleFlag = UGWS_VISIBLE;
    
    w_pCaptureMouseWnd = NULL;
    
    w_MsgQueueHead.InsertAfter(&w_MsgQueueTail);
}

NANADeskTopWnd::~NANADeskTopWnd()
{
    NANAUGMessage *pMsg;
    
    pMsg = (NANAUGMessage *)w_MsgQueueHead.GetNextNode(1);
    
    while(pMsg != &w_MsgQueueTail)
    {
        pMsg->RemoveMe();
        delete pMsg;
        
        pMsg = (NANAUGMessage *)w_MsgQueueHead.GetNextNode(1);
    }
}
    
NANAWnd * NANADeskTopWnd::GetFocusWnd()
{
    return w_pFocusWnd;
}

void NANADeskTopWnd::SetNeedForRefreshAll(int bNeedRefreshAll)
{
    w_bNeedRefreshAll = bNeedRefreshAll;
}
    
NANAWnd	* NANADeskTopWnd::SetMouseCaptureWindow(NANAWnd *pWnd)
{
    NANAWnd	*pOldCap = w_pCaptureMouseWnd;
    w_pCaptureMouseWnd = pWnd;
    return pOldCap;
}

void NANADeskTopWnd::OnPaint(void)
{
    RectFill(0,0,SCREEN_WIDTH,SCREEN_HEIGHT,DESKTOP_BKGROUND);
}


NANADeskTopWnd * NANADeskTopWnd::Instance(void)
{
	return g_pDeskTopWnd;
}
void NANADeskTopWnd::UpdateFocus(void)
{
	//寻找最前台可见窗体
	w_pFocusWnd = GetTopMostChild();
	
	DEBUG_Assert(NULL != w_pFocusWnd);
	
	while( w_pFocusWnd &&
			(!w_pFocusWnd->IsWindowVisible())
		  )
	{
		w_pFocusWnd = w_pFocusWnd->GetPreviousSibling();
	}
}

void NANADeskTopWnd::UpdateUI(void)
{
	if(w_bNeedRefreshAll)
	{
		//整个窗体(需要重绘的部分)重绘并且更新到LCD 
		PaintWindow();
		
		//重绘内容复制到DMA缓冲区中
		GHAL_RefreshAll();
		
		SetNeedForRefreshAll(0);
	}
}

//////////////////////////////////////////////////////
//
// Note that all derived message(from key-and-mouse raw input) are 
// Notify-Message which are posted by calling NotifyWindow() and
// handled by calling EmptyMessageQueue() which in turn calls the
// destwindow's OnNotify() function
//
//
void NANADeskTopWnd::EmptyMessageQueue(void)
{
	NANAUGMessage *pMsg;

	pMsg = (NANAUGMessage *)w_MsgQueueHead.GetNextNode(1);
	
	while(pMsg != &w_MsgQueueTail)
	{
		//处理消息,注意这里可能又往MessageQueue中派发了消息
		pMsg->w_pDstWnd->OnNotify(pMsg->w_pSrcWnd,pMsg->w_nMessageCode,
									pMsg->w_nParam1, pMsg->w_nParam2);
		
		pMsg->RemoveMe();
		delete pMsg;
		
		pMsg = (NANAUGMessage *)w_MsgQueueHead.GetNextNode(1);
	}
}
void NANADeskTopWnd::DispatchMouseMessage(int nMouseMessage,int x,int y)
{
	NANAWnd *pWnd;

	if(w_pCaptureMouseWnd)
	{
		//if mouse was capture by some one,first see if it's chid window
		//get the point,if no window include itself get the point,then post 
		//to it self
		pWnd = w_pCaptureMouseWnd->PointTest(x,y,0);
		if(pWnd==NULL)
		{
			pWnd = w_pCaptureMouseWnd;
		}
	}
	else
	{
		//鼠标或者指点消息需要派发到最上层的<x,y>点落在窗体矩形中的那个窗体
		pWnd = PointTest(x,y,1);
	}

	if(! pWnd) return;

	switch(nMouseMessage)
	{
	case UGRW_MOUSE_DOWN:
		pWnd->OnMouseDown(x,y);
		break;
	case UGRW_MOUSE_UP:
		pWnd->OnMouseUp(x,y);
		break;
	case UGRW_MOUSE_MOVE:
		pWnd->OnMouseMove(x,y);
		break;
	}

	EmptyMessageQueue();

	//消息派发过程并不引起重绘,派发完毕后一次性重绘
	UpdateUI();
	
}
void NANADeskTopWnd::DispatchKeyMessage(int nMessageCode,int nParam1,int nParam2)
{
	NANAFrameWnd * pFocusWnd = (NANAFrameWnd *)NANADeskTopWnd::Instance()->GetFocusWnd();
	
	//note we don't use nMessageCode for onKey
	pFocusWnd->OnKey(nParam1,nParam2);
	
	EmptyMessageQueue();
	//消息派发过程并不引起重绘,派发完毕后一次性重绘
	UpdateUI();
}
void NANADeskTopWnd::DispatchTimeCntDown(void)
{
	NANATimer * pNextTimer;
	NANATimer * pPrevTimer;
	pPrevTimer = &w_DeskTopTimer;
	pNextTimer = w_DeskTopTimer.w_pNextTimer;
	while(pNextTimer)
	{
		pNextTimer->CountDown();
		if(!pNextTimer->IsTimerAcitve())
		{
			pPrevTimer->w_pNextTimer= pNextTimer->w_pNextTimer;
			pNextTimer->w_pNextTimer = NULL;
			pNextTimer = pPrevTimer->w_pNextTimer;
		}else
		{
			pPrevTimer = pNextTimer;
			pNextTimer = pNextTimer->w_pNextTimer;
		}
	}
	EmptyMessageQueue();
	UpdateUI();
}

void NANADeskTopWnd::AddTimer (NANATimer * pTimer)
{
	NANATimer * pSecondTimer;
	pSecondTimer = w_DeskTopTimer.w_pNextTimer;
	pTimer->w_pNextTimer = pSecondTimer;
	w_DeskTopTimer.w_pNextTimer  = pTimer;
}	

void NANADeskTopWnd::RemoveTimer(NANATimer * pTimer)
{
	NANATimer * pNextTimer;
	NANATimer * pPrevTimer;
	if(NULL != pTimer)
	{
		pPrevTimer = &w_DeskTopTimer;
		pNextTimer = 	pPrevTimer->w_pNextTimer;
		while( pNextTimer )
		{
			if(pNextTimer == pTimer)
			{
				pPrevTimer->w_pNextTimer = pNextTimer->w_pNextTimer;
				
				break;
			}else
			{
				pPrevTimer = pNextTimer;
				pNextTimer = pNextTimer->w_pNextTimer;
			}
		}
	}
}
void NANADeskTopWnd::NotifyWindow(NANAWnd * pDstWnd,NANAWnd * pSrcWnd,int nMessageCode,int nParam1,int nParam2)
{
	NANAUGMessage	*pUGMsg;

	pUGMsg = new NANAUGMessage;

	pUGMsg->w_nMessageCode = nMessageCode;
	pUGMsg->w_nParam1 = nParam1 ;
	pUGMsg->w_nParam2 = nParam2 ;
	pUGMsg->w_pDstWnd = pDstWnd;
	pUGMsg->w_pSrcWnd = pSrcWnd;
	
	w_MsgQueueTail.InsertBefore( pUGMsg );
}
////////////////////////////////////////////
NANAWnd::NANAWnd()
{
	w_pFirstChildWnd = NULL;
	w_pNextSiblingWnd = NULL;
	w_pParentWnd = NULL;
	w_PrevCaptureWnd = NULL;
}

NANAWnd::~NANAWnd()
{
}



NANAWnd * NANAWnd::GetPreviousSibling(void)
{
	
	NANAWnd *pPrevSibling = w_pParentWnd->w_pFirstChildWnd;
	
	if(pPrevSibling == this) 
	{
		//本窗体就是第一个窗体,他没有前兄弟节点
		return NULL;
	}
	
	while(pPrevSibling &&
			pPrevSibling->w_pNextSiblingWnd != this)
	{
		pPrevSibling = pPrevSibling->w_pNextSiblingWnd;
	}
	
	return pPrevSibling;
}

void NANAWnd::SetUIDirty(int bDirty)
{
	w_bDirty = bDirty;
	
	if(bDirty)
	{
		NANADeskTopWnd::Instance()->SetNeedForRefreshAll(1);

		//当一个窗体为Dirty的时候,他所有的子窗体都会变为Dirty
		//但是当一个窗体为非Dirty的时候,并不代表他所有的子窗体都不为Dirty
		
		if(w_pFirstChildWnd)
		{
			w_pFirstChildWnd->SetUIDirty(bDirty);
		}
		
		//当一个窗体为Dirty的时候,他的高层兄弟窗体都会变为Dirty
		if(w_pNextSiblingWnd)
		{
			w_pNextSiblingWnd->SetUIDirty(bDirty);
		}

		//当一个窗体为Dirty的时候,他父窗体的高层兄弟窗体都会变为Dirty
		if(w_pParentWnd)
		{
			if(w_pParentWnd->w_pNextSiblingWnd)
			{
				w_pParentWnd->w_pNextSiblingWnd->SetUIDirty(bDirty);
			}
			
		}
	}
}

NANAWnd * NANAWnd::GetTopMostChild(void)
{
	NANAWnd *pChild = w_pFirstChildWnd;
	NANAWnd *pLastChild = NULL;
	
	while(pChild)
	{
		pLastChild = pChild;
		pChild = pChild->w_pNextSiblingWnd;
	}
	
	return pLastChild;
}

void NANAWnd::AppendNewChild(NANAWnd *pNewChildWnd)
{
	NANAWnd *pLastChild = GetTopMostChild();
	
	if(pLastChild)
	{
		DEBUG_Assert(NULL==pLastChild->w_pNextSiblingWnd);
		pLastChild->w_pNextSiblingWnd = pNewChildWnd;
	}
	else
	{
		w_pFirstChildWnd = pNewChildWnd;
	}
	pNewChildWnd->w_pNextSiblingWnd = NULL;
	
	pNewChildWnd->w_pParentWnd = this;
}
void NANAWnd::InsertNewChild(NANAWnd *pNewChildWnd)
{
	pNewChildWnd->w_pParentWnd = this;
 	pNewChildWnd->w_pNextSiblingWnd = w_pFirstChildWnd;

	w_pFirstChildWnd  = pNewChildWnd;
	
}
void NANAWnd::RemoveChild(NANAWnd *pRemoveChild)
{
	DEBUG_Assert(pRemoveChild->w_pParentWnd == this);
	
	if(pRemoveChild == w_pFirstChildWnd)
	{
		w_pFirstChildWnd = w_pFirstChildWnd->w_pNextSiblingWnd;
	}
	else
	{
		NANAWnd *pPrevWnd = pRemoveChild->GetPreviousSibling();
		
		pPrevWnd->w_pNextSiblingWnd = pRemoveChild->w_pNextSiblingWnd;
	}
	
	pRemoveChild->w_pParentWnd = NULL;
	pRemoveChild->w_pNextSiblingWnd = NULL;
	
}
//////////////////////////////////////////////////////

int	NANAWnd::CreateWnd(
				NANAWnd *pParentWindow,
				int nX1,
				int nY1,
				int nWidth,
				int nHeight,
				int nStyleFlag)

{
	
	w_nStyleFlag = nStyleFlag;
	w_Rect.w_nX1 = nX1;
	w_Rect.w_nX2 = nX1 +  nWidth;
	w_Rect.w_nY1 = nY1;
	w_Rect.w_nY2 = nY1 + nHeight;
	if(NULL == pParentWindow)
	{
		pParentWindow = (NANAWnd*)NANADeskTopWnd::Instance();
	}
	
	pParentWindow->AppendNewChild(this);
	
	//更新焦点窗体,新增加的窗体可能是最前台窗体
	NANADeskTopWnd::Instance()->UpdateFocus();
	
	OnCreate();
	
	w_pParentWnd->SetUIDirty(1);

	return 1;
}
void NANAWnd::CloseWindow()
{
	NANAWnd *pOldParentWnd = w_pParentWnd;

	OnClose();
	
	pOldParentWnd->RemoveChild(this);
	
	//更新焦点窗体,关闭的窗体可能是最前台窗体
	NANADeskTopWnd::Instance()->UpdateFocus();
	
	pOldParentWnd->SetUIDirty(1);
}
void NANAWnd::NotifyWindow(NANAWnd *pDstWnd,int nMessageCode,int nParam1,int nParam2)
{
	NANADeskTopWnd::Instance()->NotifyWindow(pDstWnd, this,nMessageCode, nParam1, nParam2);
}

void NANAWnd::SetWindowVisible(int bVisible)
{
	if(bVisible)
	{
		w_nStyleFlag |= UGWS_VISIBLE;
	}
	else
	{
		w_nStyleFlag &= ~UGWS_VISIBLE;
	}
	
	NANADeskTopWnd::Instance()->UpdateFocus();
	
	w_pParentWnd->SetUIDirty(1);
}

int NANAWnd::IsWindowVisible(void)
{
	return (w_nStyleFlag & UGWS_VISIBLE);
}
void NANAWnd::MoveWindowForeground(void)
{
	NANAWnd *pParentWnd;
	pParentWnd = w_pParentWnd;
	
	pParentWnd->RemoveChild(this);
	pParentWnd->AppendNewChild(this);
	
	NANADeskTopWnd::Instance()->UpdateFocus();
	
	w_pParentWnd->SetUIDirty(1);
}

void NANAWnd::MoveWindowBackground(void)
{
	NANAWnd *pParentWnd;
	pParentWnd = w_pParentWnd;
	
	pParentWnd->RemoveChild(this);
	pParentWnd->InsertNewChild(this);
	
	NANADeskTopWnd::Instance()->UpdateFocus();
	
	w_pParentWnd->SetUIDirty(1);
}


void NANAWnd::GetWindowRect(NANARect *pRect)
{
	pRect->w_nX1 = w_Rect.w_nX1;
	pRect->w_nX2 = w_Rect.w_nX2;
	pRect->w_nY1 = w_Rect.w_nY1;
	pRect->w_nY2 = w_Rect.w_nY2;
}

void NANAWnd::MoveTo(int nX,int nY)
{
	w_Rect.MoveTo(nX,nY);
	
	w_pParentWnd->SetUIDirty(1);
}

void NANAWnd::Move(int xOffset,int yOffset)
{
	w_Rect.MoveBy(xOffset,yOffset);
	
	w_pParentWnd->SetUIDirty(1);
}

NANAWnd *	NANAWnd::GetParentWnd(void)
{
	return w_pParentWnd;
}

void NANAWnd::DestroyWindow(void)
{
	//标记父窗体为需要重绘
	w_pParentWnd->SetUIDirty(1);
	
	//销毁所有的子窗口
	while(w_pFirstChildWnd)
	{
		w_pFirstChildWnd->DestroyWindow();
		RemoveChild(w_pFirstChildWnd);
	}
	
	w_pParentWnd->RemoveChild(this);
	
	//销毁自己,派生窗体可以在自己的析构函数中释放资源
	delete this;
}

//点测试,如果输入点在自己和更高层次的窗口中,则返回窗口指针,否则返回0
NANAWnd* NANAWnd::PointTest(int x,int y,int bTestSibling)
{
	NANAWnd* pRetWnd;
	//首先派发给更高层的兄弟窗口
	if(bTestSibling && w_pNextSiblingWnd)
	{
		pRetWnd = w_pNextSiblingWnd->PointTest(x,y,1);
		if(pRetWnd) return pRetWnd;
	}

	//其次派发给更高层的子窗口
	if(IsWindowVisible())
	{
		//孩子优先获得,因为孩子层次高于自己
		if(w_pFirstChildWnd)
		{
			pRetWnd = w_pFirstChildWnd->PointTest(x,y,1);
			if(pRetWnd) return pRetWnd;
		}
		//最后检查是不是落在自己的范围内
		if(w_Rect.IsPointInside(x,y))
		{
			return this;
		}
	}
	return 0;	
}
void NANAWnd::PaintWindow(void)
{
	NANAWnd *pChildWnd;

	if(IsUIDirty())
	{
		OnPaint();
		SetUIDirty(0);
	}
	
	pChildWnd = w_pFirstChildWnd;
	while(pChildWnd)
	{
		if(pChildWnd->IsWindowVisible())
		{
            DEBUG_Assert(NULL != pChildWnd);
			//我们仅仅重绘Dirty窗口,但是当一个窗体为dirty的时候
			//他的所有子窗体也都为Dirty(SetUIDirty()函数做到的),
			//因此我们能够保证这里将会对脏窗体重绘。
			pChildWnd->PaintWindow();
		}
		pChildWnd = pChildWnd->w_pNextSiblingWnd;
	}	
}

void NANAWnd::CaptureMouse(void)
{
	w_PrevCaptureWnd = NANADeskTopWnd::Instance()->SetMouseCaptureWindow(this);
}
void NANAWnd::ReleaseMouse(void)
{
	NANADeskTopWnd::Instance()->SetMouseCaptureWindow(w_PrevCaptureWnd);
}

///////////////////////////////////////////////////////////////////
NANATimer::NANATimer(NANAWnd * pCurWnd )
{
	w_pWnd = pCurWnd;
	w_nTimerPeriod = 0;
	w_nTimerCount = 0;
	w_pNextTimer = NULL;
}

void NANATimer::TimeOut(void)
{
	w_pWnd->OnTimer(this);
}

int NANATimer::IsTimerAcitve(void)
{
	if((w_nTimerCount == 0) &&(w_nTimerPeriod==0)) 
	{
		return (0);
	}else
	{
		return (1);
	}
}

void NANATimer::Start(int nCnt , int nPeriod)
{
	NANADeskTopWnd::Instance()->RemoveTimer( this );
	w_nTimerCount = nCnt;
	w_nTimerPeriod = nPeriod;
	NANADeskTopWnd::Instance()->AddTimer(this);
}

void NANATimer::Stop(void)
{
	NANADeskTopWnd::Instance()->RemoveTimer( this );
}
void NANATimer::CountDown(void)
{
	if( w_nTimerCount > 0 )
	{
		w_nTimerCount -- ;
		if(w_nTimerCount == 0)
		{
			w_nTimerCount = w_nTimerPeriod;
			TimeOut();
		}
	}
}

/////////////////////////////////////////////////////////////////

void NANALayouterTarget::DoLayout()
{
	for(int i=0;i<w_nLayouterCount;i++)
	{
		(w_pLayouterArray[i])->DoLayout();
	}
}

void NANALayouterTarget::AddLayouter(NANALayouter * pLayouter)
{
	w_pLayouterArray[w_nLayouterCount] = pLayouter;
	w_nLayouterCount ++;
}




#endif

⌨️ 快捷键说明

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