duilib 自定义控件TeamList 继承与CListUI


XML


以下是duilib demo加自己的改动



//节点
struct NodeData
{
	int level_;//层数
	bool child_visible_;//是否显示子节点
	CListContainerElementUI* list_elment_;//控件指针
	bool folder_;//是否是父节点
	bool has_child_;//有无子节点

	CDuiString value;//id
	CDuiString logo;//头像
	CDuiString text_;//昵称
	CDuiString description;//签名
	CDuiString elseinfo;//其他附加信息

	std::vector<CDuiString>  m_OtherControlsNames;//记录其他控件的名字(see,kick ,invite)

	void SetOtherControlVisible(bool bSeeVisible , bool  bInviteVisible, bool  bKickVisible )
	{
		if (list_elment_){
			for (auto  it  =m_OtherControlsNames.begin();it!= m_OtherControlsNames.end();it++)
			{
				CControlUI  * temp  =  list_elment_->FindSubControl(*it);
				if( temp ){
					CDuiString   szName  = temp->GetName();
					if(  szName.Find(L"see")  != -1){
						temp->SetVisible(bSeeVisible);
					}
					if(  szName.Find(L"kick")  != -1){
						temp->SetVisible(bKickVisible);
					}
					if(  szName.Find(L"invite")  != -1){
						temp->SetVisible(bInviteVisible);
					}
				}
			}
		}
	}
};
class Node
{
public:
	Node(): parent_(NULL)
	{
		InitializeCriticalSection(&m_cri);
	}
	explicit Node(NodeData t): data_(t), parent_(NULL)
	{

	}
	Node(NodeData t, Node* parent): data_ (t), parent_ (parent)
	{

	}
	~Node()
	{
		for (int i = 0; i < num_children(); ++i)
			delete children_[i]; 

		DeleteCriticalSection(&m_cri);
	}

	int num_children() const
	{
		//EnterCriticalSection(&m_cri);
		int  iSize  = (int)children_.size();
		//LeaveCriticalSection(&m_cri);
		return iSize;
	}

	Node* child(int i)
	{
		return children_[i];
	}

	Node* parent()
	{
		return ( parent_);
	}

	bool Node::has_children() const
	{
		return num_children() > 0;
	}

	bool folder() const
	{
		return data_.folder_;
	}

	void add_child(Node* child)
	{
		EnterCriticalSection(&m_cri);
		child->set_parent(this); 
		children_.push_back(child); 
		LeaveCriticalSection(&m_cri);
	}


	void remove_child(Node* child)
	{
		EnterCriticalSection(&m_cri);
		Children::iterator iter = children_.begin();
		for (; iter < children_.end(); ++iter)
		{
			if (*iter == child) 
			{
				iter =children_.erase(iter);
				return;
			}
		}
		LeaveCriticalSection(&m_cri);
	}

	Node* get_last_child()
	{
		if (has_children())
		{
			return child(num_children() - 1)->get_last_child();
		}
		return this;
	}
	NodeData& data()
	{
		return data_;
	}

private:
	void set_parent(Node* parent)
	{
		parent_ = parent;
	}

private:
	typedef std::vector <Node*>	Children;

	Children	children_;
	Node*		parent_;

	NodeData    data_;
	CRITICAL_SECTION  m_cri;
};

//队员信息
struct FriendListItemInfo
{
	bool folder;//是否是父节点
	bool empty;//有无子节点

	CDuiString id;//唯一标识
	CDuiString logo;//头像
	CDuiString nick_name;//昵称
	CDuiString description;//签名
	CDuiString elseinfo; //其他附加信息
};
//队伍列表
class CFriendsUI:public CListUI
{
public:
	enum {SCROLL_TIMERID = 10};

	CFriendsUI(CPaintManagerUI& paint_manager)
		: root_node_(NULL)
		, delay_deltaY_(0)
		, delay_number_(0)
		, delay_left_(0)
		, level_text_start_pos_(1)
		, text_padding_(1, 0, 0, 0)
		, paint_manager_(paint_manager)
		,kLogoButtonControlName(_T("logo"))
		,kLogoContainerControlName(_T("logo_container"))
		,kNickNameControlName (_T("nickname"))
		,kDescriptionControlName(_T("description"))
		,kOperatorPannelControlName(_T("operation"))
		, level_expand_image_(_T("<i list_icon_b.png>"))
		, level_collapse_image_(_T("<i list_icon_a.png>"))
	{
		SetItemShowHtml(true);

		kFriendListItemNormalHeight = 27;
		kFriendListItemSelectedHeight = 50;

		root_node_ = new Node;
		root_node_->data().level_ = -1;
		root_node_->data().child_visible_ = true;
		root_node_->data().has_child_ = true;
		root_node_->data().list_elment_ = NULL;

		ChildNickname_TextPadding.left =5;
	}

	~CFriendsUI()
	{
		if (root_node_)
			delete root_node_;

		root_node_ = NULL;
	}

	void SetItemSelectedBkColor(DWORD  ChildItemSelectedBkColor,DWORD ParentItemSelectedBkColor)
	{
		m_dChildItemSelectedBkColor  =ChildItemSelectedBkColor;
		m_dParentItemSelectedBkColor = ParentItemSelectedBkColor;
	}

	void SetChildNickNameTextPadding(CDuiRect  rc)
	{
		ChildNickname_TextPadding  = rc;
	}

	void SetListItemHeight(int iListItemNormalHeight,int iListItemSelectedHeight)//设置某一行的正常高度和点击后的高度
	{
		 kFriendListItemNormalHeight = iListItemNormalHeight;
		 kFriendListItemSelectedHeight = iListItemSelectedHeight;
	}

	void SetListItemXmlPath(CDuiString  itemxmlPath)//设置某一行的XML路径
	{
		m_itemxmlPath.Assign(itemxmlPath);
	}
	//因为每一个节点的xml都是一样的,所以要设置某一节点或行xml里面的控件id,一边处理各自的事件,但必须先在xml里给控件命名
	void SetOtherControlsNeedReNamed(std::map<CDuiString,CDuiString> OtherControlsNeedReNamed )
	{
		m_OtherControlsNeedReNamed  =OtherControlsNeedReNamed;
	}

	void SetOtherControlsSetVisibility(std::map<CDuiString,bool> OtherControlsSetVisibility )
	{
		m_OtherControlsSetVisibility  =OtherControlsSetVisibility;
	}

	bool Add(CControlUI* pControl)
	{
		if (!pControl)
			return false;

		if (_tcsicmp(pControl->GetClass(), _T("ListContainerElementUI")) != 0)
			return false;

		return CListUI::Add(pControl);
	}

	bool AddAt(CControlUI* pControl, int iIndex)
	{
		if (!pControl)
			return false;

		if (_tcsicmp(pControl->GetClass(), _T("ListContainerElementUI")) != 0)
			return false;

		return CListUI::AddAt(pControl, iIndex);
	}

	bool Remove(CControlUI* pControl)
	{
		if (!pControl)
			return false;

		if (_tcsicmp(pControl->GetClass(), _T("ListContainerElementUI")) != 0)
			return false;

		if (reinterpret_cast<Node*>(static_cast<CListContainerElementUI*>(pControl->GetInterface(_T("ListContainerElement")))->GetTag()) == NULL)
			return CListUI::Remove(pControl);
		else
			return RemoveNode(reinterpret_cast<Node*>(static_cast<CListContainerElementUI*>(pControl->GetInterface(_T("ListContainerElement")))->GetTag()));
	}

	bool RemoveAt(int iIndex)
	{
		CControlUI* pControl = GetItemAt(iIndex);
		if (!pControl)
			return false;

		if (_tcsicmp(pControl->GetClass(), _T("ListContainerElementUI")) != 0)
			return false;

		if (reinterpret_cast<Node*>(static_cast<CListContainerElementUI*>(pControl->GetInterface(_T("ListContainerElement")))->GetTag()) == NULL)
			return CListUI::RemoveAt(iIndex);
		else
			return RemoveNode(reinterpret_cast<Node*>(static_cast<CListContainerElementUI*>(pControl->GetInterface(_T("ListContainerElement")))->GetTag()));
	}

	void RemoveAll()
	{
		CListUI::RemoveAll();
		for (int i = 0; i < root_node_->num_children(); ++i)
		{
			Node* child = root_node_->child(i);
			RemoveNode(child);
		}
		delete root_node_;

		root_node_ = new Node;
		root_node_->data().level_ = -1;
		root_node_->data().child_visible_ = true;
		root_node_->data().has_child_ = true;
		root_node_->data().list_elment_ = NULL;
	}

	void RemoveAllButMe(Node* node)
	{
		for (int i = 0; i < root_node_->num_children(); ++i)
		{
			Node* child = root_node_->child(i);
			if(child !=node){
				RemoveNode(child);
			}
		}
	}

	void DoEvent(TEventUI& event) 
	{
		if (!IsMouseEnabled() && event.Type > UIEVENT__MOUSEBEGIN && event.Type < UIEVENT__MOUSEEND)
		{
			if (m_pParent != NULL)
				m_pParent->DoEvent(event);
			else
				CVerticalLayoutUI::DoEvent(event);
			return;
		}

		if (event.Type == UIEVENT_TIMER && event.wParam == SCROLL_TIMERID)
		{
			if (delay_left_ > 0)
			{
				--delay_left_;
				SIZE sz = GetScrollPos();
				LONG lDeltaY =  (LONG)(CalculateDelay((double)delay_left_ / delay_number_) * delay_deltaY_);
				if ((lDeltaY > 0 && sz.cy != 0)  || (lDeltaY < 0 && sz.cy != GetScrollRange().cy ))
				{
					sz.cy -= lDeltaY;
					SetScrollPos(sz);
					return;
				}
			}
			delay_deltaY_ = 0;
			delay_number_ = 0;
			delay_left_ = 0;
			m_pManager->KillTimer(this, SCROLL_TIMERID);
			return;
		}
// 		if (event.Type == UIEVENT_SCROLLWHEEL)
// 		{
// 			LONG lDeltaY = 0;
// 			if (delay_number_ > 0)
// 				lDeltaY =  (LONG)(CalculateDelay((double)delay_left_ / delay_number_) * delay_deltaY_);
// 			switch (LOWORD(event.wParam))
// 			{
// 			case SB_LINEUP:
// 				if (delay_deltaY_ >= 0)
// 					delay_deltaY_ = lDeltaY + 8;
// 				else
// 					delay_deltaY_ = lDeltaY + 12;
// 				break;
// 			case SB_LINEDOWN:
// 				if (delay_deltaY_ <= 0)
// 					delay_deltaY_ = lDeltaY - 8;
// 				else
// 					delay_deltaY_ = lDeltaY - 12;
// 				break;
// 			}
// 			if
// 				(delay_deltaY_ > 100) delay_deltaY_ = 100;
// 			else if
// 				(delay_deltaY_ < -100) delay_deltaY_ = -100;
// 
// 			delay_number_ = (DWORD)sqrt((double)abs(delay_deltaY_)) * 5;
// 			delay_left_ = delay_number_;
// 			m_pManager->SetTimer(this, SCROLL_TIMERID, 50U);
// 			return;
// 		}

		CListUI::DoEvent(event);
	}

	Node* GetRoot()
	{
		return root_node_;
	}

	static bool OnLogoButtonEvent(void* event) {
		if( ((TEventUI*)event)->Type == UIEVENT_BUTTONDOWN ) {
			CControlUI* pButton = ((TEventUI*)event)->pSender;
			if( pButton != NULL ) {
				CListContainerElementUI* pListElement = (CListContainerElementUI*)(pButton->GetTag());
				if( pListElement != NULL ) pListElement->DoEvent(*(TEventUI*)event);
			}
		}
		return true;
	}

	Node* AddNode(const FriendListItemInfo& item, Node* parent)
	{
		if (!parent)
			parent = root_node_;

		TCHAR szBuf[MAX_PATH] = {0};

		CListContainerElementUI* pListElement = NULL;
		if( !m_dlgBuilder.GetMarkup()->IsValid() ) {
			pListElement = static_cast<CListContainerElementUI*>(m_dlgBuilder.Create(m_itemxmlPath.GetData(), (UINT)0, NULL, &paint_manager_));
		}
		else {
			pListElement = static_cast<CListContainerElementUI*>(m_dlgBuilder.Create((UINT)0, &paint_manager_));
		}
		if (pListElement == NULL)
			return NULL;

		Node* node = new Node;
		node->data().value = item.id;
		node->data().logo  = item.logo;
		node->data().text_ = item.nick_name;
		node->data().description = item.description;
		node->data().elseinfo  = item.elseinfo;

		node->data().level_ = parent->data().level_ + 1;
		if (item.folder)
			node->data().has_child_ = !item.empty;
		else
			node->data().has_child_ = false;

		node->data().folder_ = item.folder;

		node->data().child_visible_ = (node->data().level_ == 0);
		node->data().child_visible_ = false;


		node->data().list_elment_ = pListElement;

		if (!parent->data().child_visible_)
			pListElement->SetVisible(false);

		if (parent != root_node_ && !parent->data().list_elment_->IsVisible())
			pListElement->SetVisible(false);

		CDuiRect rcPadding = text_padding_;
		for (int i = 0; i < node->data().level_; ++i)
		{
			rcPadding.left += level_text_start_pos_;		
		}
		pListElement->SetPadding(rcPadding);

		pListElement->SetName(item.id);//设置一项的控件ID

		//设置xml里控件可见
// 		for ( auto it=m_OtherControlsSetVisibility.begin();  it !=m_OtherControlsSetVisibility.end();it++)
// 		{
// 			if (pListElement->FindSubControl(it->first)){
// 				(pListElement->FindSubControl(it->first))->SetVisible(it->second);
// 			}
// 		}

		//给xml里的控件重新命名,方便处理消息
		for ( auto it=m_OtherControlsNeedReNamed.begin();  it !=m_OtherControlsNeedReNamed.end();it++)
		{
			if (pListElement->FindSubControl(it->first)){
				node->data().m_OtherControlsNames.push_back(it->second);
				(pListElement->FindSubControl(it->first))->SetTag((UINT_PTR)node);
				(pListElement->FindSubControl(it->first))->SetName(it->second);
			}
		}


		CButtonUI* log_button = static_cast<CButtonUI*>(paint_manager_.FindSubControlByName(pListElement, kLogoButtonControlName));
		if (log_button != NULL)
		{
			if (!item.folder && !item.logo.IsEmpty())
			{
#if defined(UNDER_WINCE)
				_stprintf(szBuf, _T("%s"), item.logo);
#else
				_stprintf_s(szBuf, MAX_PATH - 1, _T("%s"), item.logo);
#endif
				log_button->SetNormalImage(szBuf);
			}
			else
			{
				CContainerUI* logo_container = static_cast<CContainerUI*>(paint_manager_.FindSubControlByName(pListElement, kLogoContainerControlName));
				if (logo_container != NULL)
					logo_container->SetVisible(false);
			}
			log_button->SetTag((UINT_PTR)pListElement);
			log_button->OnEvent += MakeDelegate(&OnLogoButtonEvent);
		}

		CDuiString html_text;
		if (node->data().has_child_)
		{
			if (node->data().child_visible_)
				html_text += level_expand_image_;
			else
				html_text += level_collapse_image_;

#if defined(UNDER_WINCE)
			_stprintf(szBuf, _T("<x %d>"), level_text_start_pos_);
#else
			_stprintf_s(szBuf, MAX_PATH - 1, _T("<x %d>"), level_text_start_pos_);
#endif
			html_text += szBuf;
		}

		if (item.folder){
			html_text += node->data().text_;
		}else{
#if defined(UNDER_WINCE)
			_stprintf(szBuf, _T("%s"), item.nick_name);
#else
			_stprintf_s(szBuf, MAX_PATH - 1, _T("%s"), item.nick_name);
#endif
			html_text += szBuf;
		}

		CLabelUI* nick_name = static_cast<CLabelUI*>(paint_manager_.FindSubControlByName(pListElement, kNickNameControlName));
		if (nick_name != NULL)
		{
			if (item.folder){
				nick_name->SetFixedWidth(0);
				nick_name->SetTextColor(0xffCECC02);
				//加粗群名
				std_string  gName,szTemp;
				gName.Assign(html_text);
				szTemp.AppendFormat("<b>%s</b>",gName.c_str());
				nick_name->SetText(CA2T(szTemp.c_str()));
			}else{
				nick_name->SetTextPadding(ChildNickname_TextPadding);
				nick_name->SetText(html_text);
			}
			nick_name->SetShowHtml(true);

			//nick_name->SetText(html_text);
			nick_name->SetTag((UINT_PTR)node);
		}

		if (!item.folder && !item.description.IsEmpty())
		{
			CLabelUI* description = static_cast<CLabelUI*>(paint_manager_.FindSubControlByName(pListElement, kDescriptionControlName));
			if (description != NULL)
			{
#if defined(UNDER_WINCE)
				_stprintf(szBuf, _T("<x 20><c #808080>%s</c>"), item.description);
#else
				//_stprintf_s(szBuf, MAX_PATH - 1, _T("<x 20><c #808080>%s</c>"), item.description);
				_stprintf_s(szBuf, MAX_PATH - 1, _T("<x 20>%s"), item.description);
#endif
				description->SetShowHtml(true);
				description->SetText(szBuf);
				description->SetTag((UINT_PTR)node);
			}
		}

		pListElement->SetFixedHeight(kFriendListItemNormalHeight);
		pListElement->SetTag((UINT_PTR)node);
		int index = 0;
		if (parent->has_children())
		{
			Node* prev = parent->get_last_child();
			index = prev->data().list_elment_->GetIndex() + 1;
		}else 
		{
			if (parent == root_node_)
				index = 0;
			else
				index = parent->data().list_elment_->GetIndex() + 1;
		}
		if (!CListUI::AddAt(pListElement, index))
		{
			delete pListElement;
			delete node;
			node = NULL;
		}

		parent->add_child(node);
		return node;
	}

	Node* AddNode(const FriendListItemInfo& item, Node* parent, DuiLib::STRINGorID  itemxmlPath)
	{
		if (!parent)
			parent = root_node_;

		TCHAR szBuf[MAX_PATH] = {0};

		CListContainerElementUI* pListElement = NULL;
		if( !m_dlgBuilder.GetMarkup()->IsValid() ) {
			pListElement = static_cast<CListContainerElementUI*>(m_dlgBuilder.Create(itemxmlPath,(UINT)0, NULL, &paint_manager_));
		}
		else {
			pListElement = static_cast<CListContainerElementUI*>(m_dlgBuilder.Create((UINT)0, &paint_manager_));
		}
		if (pListElement == NULL)
			return NULL;

		pListElement->SetName(item.id);//设置整个项的控件ID

		//设置xml里控件可见
		for ( auto it=m_OtherControlsSetVisibility.begin();  it !=m_OtherControlsSetVisibility.end();it++)
		{
			if (pListElement->FindSubControl(it->first)){
				(pListElement->FindSubControl(it->first))->SetVisible(it->second);
			}
		}
		//给xml里的控件重新命名,方便处理消息
		for ( auto it=m_OtherControlsNeedReNamed.begin();  it !=m_OtherControlsNeedReNamed.end();it++)
		{
			if (pListElement->FindSubControl(it->first)){
				(pListElement->FindSubControl(it->first))->SetName(it->second);
			}
		}

		Node* node = new Node;
		node->data().value = item.id;
		node->data().logo  = item.logo;
		node->data().text_ = item.nick_name;
		node->data().description = item.description;
		node->data().elseinfo  = item.elseinfo;


		node->data().level_ = parent->data().level_ + 1;
		if (item.folder)
			node->data().has_child_ = !item.empty;
		else
			node->data().has_child_ = false;

		node->data().folder_ = item.folder;

		node->data().child_visible_ = (node->data().level_ == 0);
		node->data().child_visible_ = false;

		node->data().list_elment_ = pListElement;

		if (!parent->data().child_visible_)
			pListElement->SetVisible(false);

		if (parent != root_node_ && !parent->data().list_elment_->IsVisible())
			pListElement->SetVisible(false);

		CDuiRect rcPadding = text_padding_;
		for (int i = 0; i < node->data().level_; ++i)
		{
			rcPadding.left += level_text_start_pos_;		
		}
		pListElement->SetPadding(rcPadding);

		CButtonUI* log_button = static_cast<CButtonUI*>(paint_manager_.FindSubControlByName(pListElement, kLogoButtonControlName));
		if (log_button != NULL)
		{
			if (!item.folder && !item.logo.IsEmpty())
			{
#if defined(UNDER_WINCE)
				_stprintf(szBuf, _T("%s"), item.logo);
#else
				_stprintf_s(szBuf, MAX_PATH - 1, _T("%s"), item.logo);
#endif
				log_button->SetNormalImage(szBuf);
			}
			else
			{
				CContainerUI* logo_container = static_cast<CContainerUI*>(paint_manager_.FindSubControlByName(pListElement, kLogoContainerControlName));
				if (logo_container != NULL)
					logo_container->SetVisible(false);
			}
			log_button->SetTag((UINT_PTR)pListElement);
			log_button->OnEvent += MakeDelegate(&OnLogoButtonEvent);
		}

		CDuiString html_text;
		if (node->data().has_child_)
		{
			if (node->data().child_visible_)
				html_text += level_expand_image_;
			else
				html_text += level_collapse_image_;

#if defined(UNDER_WINCE)
			_stprintf(szBuf, _T("<x %d>"), level_text_start_pos_);
#else
			_stprintf_s(szBuf, MAX_PATH - 1, _T("<x %d>"), level_text_start_pos_);
#endif
			html_text += szBuf;
		}

		if (item.folder)
		{
			html_text += node->data().text_;
		}
		else
		{
#if defined(UNDER_WINCE)
			_stprintf(szBuf, _T("%s"), item.nick_name);
#else
			_stprintf_s(szBuf, MAX_PATH - 1, _T("%s"), item.nick_name);
#endif
			html_text += szBuf;
		}

		CLabelUI* nick_name = static_cast<CLabelUI*>(paint_manager_.FindSubControlByName(pListElement, kNickNameControlName));
		if (nick_name != NULL)
		{
			if (item.folder){
				nick_name->SetFixedWidth(0);
			}else{
				nick_name->SetTextPadding(ChildNickname_TextPadding);
			}
			nick_name->SetShowHtml(true);
			nick_name->SetText(html_text);
		}

		if (!item.folder && !item.description.IsEmpty())
		{
			CLabelUI* description = static_cast<CLabelUI*>(paint_manager_.FindSubControlByName(pListElement, kDescriptionControlName));
			if (description != NULL)
			{
#if defined(UNDER_WINCE)
				_stprintf(szBuf, _T("<x 20><c #808080>%s</c>"), item.description);
#else
				_stprintf_s(szBuf, MAX_PATH - 1, _T("<x 20>%s"), item.description);
#endif
				description->SetShowHtml(true);
				description->SetText(szBuf);
			}
		}

		pListElement->SetFixedHeight(kFriendListItemNormalHeight);
		pListElement->SetTag((UINT_PTR)node);
		int index = 0;
		if (parent->has_children())
		{
			Node* prev = parent->get_last_child();
			index = prev->data().list_elment_->GetIndex() + 1;
		}
		else 
		{
			if (parent == root_node_)
				index = 0;
			else
				index = parent->data().list_elment_->GetIndex() + 1;
		}
		if (!CListUI::AddAt(pListElement, index))
		{
			delete pListElement;
			delete node;
			node = NULL;
		}

		parent->add_child(node);
		return node;
	}

	bool RemoveNode(Node* node)
	{
		if (!node || node == root_node_) return false;

		for (int i = 0; i < node->num_children(); ++i)
		{
			Node* child = node->child(i);
			RemoveNode(child);
		}

		CListUI::Remove(node->data().list_elment_);
		node->parent()->remove_child(node);
		delete node;

		return true;
	}

	bool RemoveElseParentNode(Node* node)
	{
		if (!node || node == root_node_) return false;
		if(!node->folder())   return false;

		int iCount=  ( node->parent() )->num_children();
		for (int i =0;i<iCount;i++)
		{
			Node* child = node->parent()->child(i);
			if(child !=node){
				RemoveNode(child);
				break;
			}
		}
		return true;
	}

	void SetChildVisible(Node* node, bool visible)
	{
		if (!node || node == root_node_)
			return;

		if (node->data().child_visible_ == visible)
			return;

		node->data().child_visible_ = visible;

		TCHAR szBuf[MAX_PATH] = {0};
		CDuiString html_text;
		if (node->data().has_child_)
		{
			if (node->data().child_visible_)
				html_text += level_expand_image_;
			else
				html_text += level_collapse_image_;

#if defined(UNDER_WINCE)
			_stprintf(szBuf, _T("<x %d>"), level_text_start_pos_);
#else
			_stprintf_s(szBuf, MAX_PATH - 1, _T("<x %d>"), level_text_start_pos_);
#endif
			html_text += szBuf;

			html_text += node->data().text_;

			CLabelUI* nick_name = static_cast<CLabelUI*>(paint_manager_.FindSubControlByName(node->data().list_elment_, kNickNameControlName));
			if (nick_name != NULL)
			{
				nick_name->SetShowHtml(true);
				nick_name->SetText(html_text);
			}
		}

		if (!node->data().list_elment_->IsVisible())
			return;

		if (!node->has_children())
			return;

		Node* begin = node->child(0);
		Node* end = node->get_last_child();
		if(  (!begin)   ||  (!end)  ||   (!begin->data().list_elment_)  ||  (!end->data().list_elment_) ){
			return;
		}
		for (int i = begin->data().list_elment_->GetIndex(); i <= end->data().list_elment_->GetIndex(); ++i)
		{
			CControlUI* control = GetItemAt(i);
			if(control){
				if (_tcsicmp(control->GetClass(), _T("ListContainerElementUI")) == 0)
				{
					if (visible) 
					{
						Node* local_parent = ((Node*)control->GetTag())->parent();
						if(local_parent){
							if (local_parent->data().child_visible_ && local_parent->data().list_elment_->IsVisible())
							{
								control->SetVisible(true);
							}
						}
					}
					else
					{
						control->SetVisible(false);
					}
				}
			}
		}
	}

	bool CanExpand(Node* node) const
	{
		if (!node || node == root_node_)
			return false;

		return node->data().has_child_;
	}

	bool SelectItem(int iIndex, bool bTakeFocus)
	{
		if( iIndex == m_iCurSel ) return true;

		// We should first unselect the currently selected item
		if( m_iCurSel >= 0 ) {
			CControlUI* pControl = GetItemAt(m_iCurSel);
			if( pControl != NULL) {
				IListItemUI* pListItem = static_cast<IListItemUI*>(pControl->GetInterface(_T("ListItem")));
				if( pListItem != NULL )
				{
					CListContainerElementUI* pFriendListItem = static_cast<CListContainerElementUI*>(pControl);
					Node* node = (Node*)pControl->GetTag();
					if ((pFriendListItem != NULL) && (node != NULL) && !node->folder())
					{
						pFriendListItem->SetFixedHeight(kFriendListItemNormalHeight);
						CContainerUI* pOperatorPannel = static_cast<CContainerUI*>(paint_manager_.FindSubControlByName(pFriendListItem, kOperatorPannelControlName));
						if (pOperatorPannel != NULL)
						{
							pOperatorPannel->SetVisible(false);
						}
					}
					pListItem->Select(false);
				}
			}

			m_iCurSel = -1;
		}

		if( iIndex < 0 )
			return false;

		if (!__super::SelectItem(iIndex, bTakeFocus))
			return false;


		CControlUI* pControl = GetItemAt(m_iCurSel);
		if( pControl != NULL) {
			CListContainerElementUI* pFriendListItem = static_cast<CListContainerElementUI*>(pControl);
			Node* node = (Node*)pControl->GetTag();
			if ((pFriendListItem != NULL) && (node != NULL) && !node->folder())
			{
				pFriendListItem->SetFixedHeight(kFriendListItemSelectedHeight);
				CContainerUI* pOperatorPannel = static_cast<CContainerUI*>(paint_manager_.FindSubControlByName(pFriendListItem, kOperatorPannelControlName));
				if (pOperatorPannel != NULL){
					pOperatorPannel->SetVisible(true);
				}
				this->SetSelectedItemBkColor(m_dChildItemSelectedBkColor);
			}
			else  if ((pFriendListItem != NULL) && (node != NULL) && node->folder())
			{
				this->SetSelectedItemBkColor(m_dParentItemSelectedBkColor);
			}
		}
		return true;
	}

public:
	const TCHAR*  kLogoButtonControlName;
	const TCHAR*  kLogoContainerControlName;
	const TCHAR*  kNickNameControlName;
	const TCHAR*  kDescriptionControlName;
	const TCHAR*  kOperatorPannelControlName;
	CDuiString level_expand_image_;
	CDuiString level_collapse_image_;

	Node*	root_node_;

	int kFriendListItemNormalHeight ;
	int kFriendListItemSelectedHeight;

	int level_text_start_pos_;//有伸缩图标,则是相对于左边伸缩图标的距离;无则是距离左边界距离
	CDuiRect	text_padding_;//父节点padding

	CDuiRect  ChildNickname_TextPadding;//子节点昵称的textpadding

	LONG	delay_deltaY_;
	DWORD	delay_number_;
	DWORD	delay_left_;


	DWORD m_dChildItemSelectedBkColor;
	DWORD m_dParentItemSelectedBkColor;

	std::map<CDuiString,CDuiString>  m_OtherControlsNeedReNamed;//控件重命名
	std::map<CDuiString,bool>  m_OtherControlsSetVisibility;//设置控件可见性

	CDuiString m_itemxmlPath;

	CPaintManagerUI& paint_manager_;
	CDialogBuilder m_dlgBuilder;
};

简单用法:

const TCHAR* const kFriendsListControlName = _T("friends");

pFriendsList = static_cast<CFriendsUI*>(m_pm.FindControl(kFriendsListControlName));

	void UI_UpdateFriendList()
	{
// 		if (pFriendsList != NULL)
// 		{
// 			//
// 			std::map<CDuiString,CDuiString>  other;
// 			std::map<CDuiString,bool>  Visibility;
// 			FriendListItemInfo item;
// 			//
// 			//队长:自己显示 查;本队其他人显示   查、踢  ; 大厅的人显示  查、组;   其他队的显示  查
// 			//队员:自己显示 查;大厅的人都是显示  查;   本队的其他人显示   查  ; 其他队的  查
// 			//大厅:自己显示 查;大厅的人都是显示  查;   其他队的  查
// 			/
// 
// 			
// 			item.id = _T("2063_106");
// 			item.folder = true;
// 			item.empty = false;
// 			item.nick_name = _T("竞技魔方官方开黑(1)");
// 			Node* root_parent2 = pFriendsList->AddNode(item, NULL);
// 			friends_.push_back(item);
// 
// 			item.id = _T("106@2063_106");
// 			item.folder = false;		
// 			//item.logo = _T("friendlist\\free.png");
// 			item.nick_name = _T("凡达风风光光");
// 			item.description = _T("[太阳之井]");
// 			other.clear();
// 			other.insert(std::make_pair(L"kick",L"kick@106@2063_106"));
// 			other.insert(std::make_pair(L"invite",L"invite@106@2063_106"));
// 			other.insert(std::make_pair(L"see",L"see@106@2063_106"));
// 			pFriendsList->SetOtherControlsNeedReNamed(other);
// 			Visibility.clear();
// 			Visibility.insert(std::make_pair(L"kick",false));
// 			Visibility.insert(std::make_pair(L"invite",false));
// 			Visibility.insert(std::make_pair(L"see",true));
// 			pFriendsList->SetOtherControlsSetVisibility(Visibility);
// 
// 			pFriendsList->AddNode(item, root_parent2);
// 			friends_.push_back(item);
// 			myself_info_ = item;//保存自己
// 
// 
// 			item.id = _T("107@2063_106");
// 			item.folder = false;
// 			//item.logo = _T("friendlist\\free.png");
// 			item.nick_name = _T("sdsdsasdd");
// 			item.description = _T("[太阳之井]");
// 			other.clear();
// 			other.insert(std::make_pair(L"kick",L"kick@107@2063_106"));
// 			other.insert(std::make_pair(L"invite",L"invite@107@2063_106"));
// 			other.insert(std::make_pair(L"see",L"see@107@2063_106"));
// 			pFriendsList->SetOtherControlsNeedReNamed(other);
// 			Visibility.clear();
// 			Visibility.insert(std::make_pair(L"kick",true));
// 			Visibility.insert(std::make_pair(L"invite",false));
// 			Visibility.insert(std::make_pair(L"see",true));
// 			pFriendsList->SetOtherControlsSetVisibility(Visibility);
// 
// 			pFriendsList->AddNode(item, root_parent2);
// 			friends_.push_back(item);
// 		}
	}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值