tree.cpp

来自「自己实现的一个好用的嵌入式GUI」· C++ 代码 · 共 367 行

CPP
367
字号
#include "stdafx.h"
#include"tree.h"

///////////////////////////////////////////////////CTreeNode实现//////////////////////////////////////////////////////////
CTreeNode::CTreeNode(){
	pData = NULL;
	nindex = 0;
	id = 0;
	pcaption = NULL;
	pparent = NULL;

}
//------------------------------------------------------------------------------------------------------------------------
CTreeNode* CTreeNode::getFirstChild(){

    int nsize = this->child_vector.size();
	if(nsize>=1){
		return child_vector[0];
	}
	return NULL;
}
//------------------------------------------------------------------------------------------------------------------------
CTreeNode* CTreeNode::getSibl_forder(){
  
	CTreeNode* parent = this->pparent;
	if (!parent) {                                  //root
		return NULL;
	}
	if (parent->child_vector.size()-1<=this->nindex) {//self is the last child
		return NULL;
	}
	return parent->child_vector[nindex+1];          //get sibling
		
}
//------------------------------------------------------------------------------------------------------------------------
CTreeNode* CTreeNode::getNext_forder(){ 
	
	CTreeNode* ptmp = NULL;
	CTreeNode* presult = NULL;
	ptmp = this;
	presult = ptmp->getFirstChild();
	if(presult){                                      //get first child
		return presult;
	}
	while (ptmp){ 
		presult=ptmp->getSibl_forder();
		if (presult) {                                //if no child, get sibling
			return presult;
		}
		ptmp=ptmp->pparent;                           //if no child and sibling, get parent
	}
	return NULL;
}
//------------------------------------------------------------------------------------------------------------------------
int CTreeNode::AppendChildNode(CTreeNode* pchildNode){ 
	
   int nresult;                                       
   this->child_vector.push_back(pchildNode);          //add child
   nresult = this->child_vector.size()-1;             //return
   pchildNode->nindex = nresult;                      //child's index
   pchildNode->pparent = this;                        //child's parent
   return nresult;
}
//------------------------------------------------------------------------------------------------------------------------

bool CTreeNode::operator==(const CTreeNode& treenode)const{
	return (id == treenode.id);
}

////////////////////////////////////////////////CTree 实现//////////////////////////////////////////////////////////////
void CTree::AppendNode(CTreeNode* pparentNode, CTreeNode* pchildNode ){
	    if(pchildNode){                          //!=NULL
			if(pparentNode==NULL){
				proot = pchildNode;
				pchildNode->pparent = NULL;
			}else{
				pparentNode->AppendChildNode(pchildNode);
			
			}
		}
}
//------------------------------------------------------------------------------------------------------------------------
 
void CTree::DeleteNode(CTreeNode* pNode){                              //删除pNode为根的子树
		CTreeNode* parent = NULL;
		if(pNode){
			parent = pNode->pparent;
			if(parent){
				pNode->pparent = NULL;                              //leave parent
                Cvector_10<CTreeNode*>& thevctr = parent->child_vector;  //adjust the parent's child list
				thevctr.erase(pNode->nindex);
				for(int i=0; i<thevctr.size(); i++){
					thevctr[i]->nindex = i;
				}
			}else{                                                 //delete root node
				proot = NULL;
			}
		}	
}	

////////////////////////////////////////////////CWinManager实现///////////////////////////////////////////////////////////////
void CWinManager::AppendNode(CTreeNode* pparentNode, CTreeNode* pchildNode){
		CTree::AppendNode(pparentNode, pchildNode);
		nodeNum++;
}
//------------------------------------------------------------------------------------------------------------------------
 
void CWinManager::DeleteNode(CTreeNode* pNode){
		CTree::DeleteNode(pNode);
		nodeNum--;
}
//------------------------------------------------------------------------------------------------------------------------
 
///////////////////////////////////////////////////CWindow实现//////////////////////////////////////////////////////////

CWinManager* CWindow::winMnger = NULL;  
int CWindow::winNum = 0;
CWindow* CWindow::fhwnd = NULL;

CWindow::CWindow( int x=0, int y=0, int width=0, int lenth=0, CWindow* phwnd=NULL, char* caption="myWindow"){
		
		hwnd = this;
		this->phwnd = phwnd;
		this->phomeNode = new CTreeNode(); 
		this->phomeNode->pData = this;
		this->x = x;
		this->y = y;
		this->width = width;
		this->lenth = lenth;
		this->caption = caption;
		wintype = 0;                 //default value,win

		if(winNum==0){               //initialize the winManager
			CWindow::winMnger = new CWinManager;
			CWindow::winMnger->AppendNode(NULL, phomeNode);
			this->caption = "DeskTop";
			CWindow::winMnger->renewWinArry(CWindow::winMnger->root());//ini active win arry
		}else if(phwnd==NULL){             //choose root as parent
			CWindow::winMnger->AppendNode(CWindow::winMnger->root(), phomeNode);
			this->phwnd =(CWindow*) CWindow::winMnger->root()->pData;
		}else{
			CWindow::winMnger->AppendNode(phwnd->phomeNode, phomeNode);
			this->phwnd =(CWindow*) CWindow::winMnger->root()->pData;
		}	
		winNum++;
		OnClick = NULL;          //func pointer
		OnKeyDown = NULL;

	}
//------------------------------------------------------------------------------------------------------------------------
 
void CWindow::drawindow(){        //draw this win and its all sub wins
		drawin();            //main win
		CTreeNode* pn = this->phomeNode->getFirstChild();
		CTreeNode* pp = this->phomeNode->getSibl_forder();
		CWindow* pw = NULL;
		          
		while(pn && pn!=pp){
			pw =(CWindow*) pn->pData;
			while(pn && pw->wintype==0){ //not subwin(type==0) but text or button
				pn = pn->getSibl_forder();//skip submainwin(type==0) and it's subwin(type!=0) 				
				if(pn)
					pw = (CWindow*)pn->pData;
			}
			if(pw && pw->wintype!=0)
				pw->drawin();
			if(pn)
				pn = pn->getNext_forder();
		}
        
}
//------------------------------------------------------------------------------------------------------------------------
 
void CWindow::showindow(){
		drawindow();
		if(wintype == 0){
			CWindow::winMnger->renewWinArry(this->phomeNode);
		}
}
//------------------------------------------------------------------------------------------------------------------------
 
void CWindow::set_phwnd(CWindow* phwnd){
		this->phwnd = phwnd;
		//add this to winmanager;
		CWindow::winMnger->DeleteNode(phomeNode);//in constructor CWindow(), phomeNode has been the root's son 
		CWindow::winMnger->AppendNode(phwnd->phomeNode, phomeNode);
}
//------------------------------------------------------------------------------------------------------------------------
 
void CWindow::winProc(CMessage* pmssg){
		switch(pmssg->mssgtype){
		case 0: //click
//			getfocus();
			if(OnClick)
				(*OnClick)(pmssg);
			break;
		case 1://keydown
//			if(OnKeyDown)
//				(*OnKeyDown)(pmssg);
			break;
		}
}
//------------------------------------------------------------------------------------------------------------------------
 
void CWindow::getfocus(){
		 CWindow* fcs_hwnd = CWindow::fhwnd;
         if( fcs_hwnd && fcs_hwnd!=this ){
              fcs_hwnd->freefocus();
         }
		 CWindow::fhwnd = this;            
}
///////////////////////////////////////////////////CText实现//////////////////////////////////////////////////////////
void CText::winProc(CMessage* pmssg){
		CWindow::winProc(pmssg);
		switch(pmssg->mssgtype){
		case 1:// keydown
			if(this==CWindow::get_fhwnd()){//get focus
				if(pmssg->lparam==49){        //'^' pageup
					pageup();
				}else if (pmssg->lparam==50){ // pagedown
					pagedown();
				}else if(pmssg->lparam==51){
                    moveleft();
				}else if(pmssg->lparam==52){
				    moveright();
				}else if(pmssg->lparam=='E'){
				    delet();
				}else{
					input(pmssg->lparam);     //input a char	
				}
				textout();
			}
		//case 0://click
			//pageup();
		}
}
//------------------------------------------------------------------------------------------------------------------------
 
void CText::input(char c){
 //       int cperline = width/font_x;
		if(endpos>=buffsize){
		}else{
		
			for(int i=endpos; i>=curpos; i--){
				text[i+1] = text[i];
			}
			text[curpos] = c;     	
			curpos++;
			endpos++;
			endcol = endpos%cperline; 
			endline = endpos/cperline;
			curcol = (curpos)%cperline;
			curline = (curpos)/cperline;
		
		}
		
}
//------------------------------------------------------------------------------------------------------------------------
 
void CText::textout(){
        clearscrn(x, y+10, x+width, y+lenth);
        CDC *pDC = (AfxGetApp()->m_pMainWnd)->GetDC();
				
		if(endline>=cpercol-2 && curcol==cperline-1){
			linedown();
			clearscrn(x, y+10, x+width, y+lenth);
		}
		int dspendline = dspstartline + cpercol -2;
		dspendline = (dspendline>endline)?endline:dspendline;//get the last logic line to be displayed
               
		for(int i=dspstartline; i<=dspendline; i++){
            for(int j=0; j<cperline; j++){
				if(text[i*cperline+j]=='\0'){
					break;
				}
				pDC->TextOut(this->x+j*font_x+4, this->y+12+(i-dspstartline)*linegap, text[i*cperline+j]);
			}
		}
	//	pDC->TextOut(this->x+curcol*font_x+4, this->y+12+(curline-dspstartline)*linegap, "^");//cursor
}
//------------------------------------------------------------------------------------------------------------------------
 
void CText::drawin(){
		CDC *pDC = (AfxGetApp()->m_pMainWnd)->GetDC();
        pDC->Rectangle(CRect(x, y+10, x+width, y+lenth));
		pDC->TextOut(x+5, y-10, caption);

		textout();
		
		if(CWindow::fhwnd){
			pDC->TextOut(0, 0, CWindow::fhwnd->caption);
		}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//CMessage* click_map(int x, int y){

//};

void message_map(CMessage* pmssg){//;//, CWindow*& phwnd, CWindow*& hwnd ){//, CWindow* subWin){//暂时设成CWindow*, int,以后改成void, message
	//look at the active win arry first
	if(pmssg->hwnd){  // if the target win be given
		pmssg->hwnd->winProc(pmssg);
		return;
	}
	CWindow* phwnd = NULL;
	CWindow* hwnd = NULL;
    int x = pmssg->x;
	int y = pmssg->y;
	CTreeNode* pnode = NULL;
	Cvector_10<CTreeNode*>& theArry = CWindow::winMnger->activeWinArry;//reference
    CWindow* pwin = NULL;

	for(int i=theArry.size()-1; i>=0; i--){	
	(CWindow*) pwin = (CWindow*)(theArry[i]->pData);
		if(pwin && pwin->capture(x, y)){
			if(pwin->phomeNode!=CWindow::winMnger->root()) //keep the root at the botton of theArry
				  CWindow::winMnger->renewWinArry(pwin->phomeNode); 
			phwnd = pwin;                    //return value
			break;                            //out
		}
	}
	// not in win arry
	pnode = CWindow::winMnger->root();

	while((!phwnd) && pnode){
		pwin = (CWindow*) pnode->pData;
		if(pwin->capture(x, y) && pwin->wintype==0){  //win,not text or button     
			theArry.push_back(pnode);                 //add new pwin into the arry
			phwnd = pwin;     
		}
		pnode = pnode->getNext_forder();
	}

	//let the message map to the target win
	if(phwnd && phwnd->phomeNode!=CWindow::winMnger->root()){//to desktop, we just do draw, for other main win, we will try to get the target subwin(text or button)
		pnode = phwnd->phomeNode->getFirstChild();             
	
		while(pnode && pnode!=phwnd->phomeNode->getSibl_forder()){        //need change ,here we have not consider pnode->pData.winType==0?			
			pwin = (CWindow*)pnode->pData;              //let the message map to the target win
			if(pwin->wintype!=0 && pwin->capture(x, y)){//message get the target win(button or text, not window)
				hwnd = pwin;
				break;
			}
			pnode = pnode->getNext_forder();
		}
	}
	//draw window and response message event
	if(phwnd){// message hit a main window 
			phwnd->getfocus();
		if(phwnd->phomeNode==CWindow::winMnger->root()){ //desktop
			phwnd->drawin(); 
            
			for(int i=1; i<theArry.size(); i++){//遍历活动窗口栈,note: activeArry[0]is root node
				pwin = (CWindow*)theArry[i]->pData;
				pwin->drawindow();//画出所有活动窗口(及所有子窗口),and pushu the main win to theArry                                                             子窗口)
			}
		}else{
			phwnd->drawindow();
		}
		if(hwnd){//message hit a subwin like button, text and so on 
			hwnd->getfocus();
			hwnd->winProc(pmssg);
		}
	}

}

⌨️ 快捷键说明

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