📄 wnd.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 + -