duilib 給List表頭增加百分比控制寬度的功能

轉載請說明原出處,謝謝~~:http://blog.csdn.net/zhuhongshu/article/details/42503147


       最近項目裏需要用到包含表頭列表,而窗體大小改變後,每個列表項的寬度不會自動改變,這樣窗體變寬後列表就出現了一大片空白,非常難看。所以給列表頭增加了屬性,可以控制讓每個列表項的寬度根據百分比來計算。這樣再配合我之前寫的對List控件的增強代碼,就能讓列表項的每列按照百分比控制寬度。


      分別要給CListHeaderUI類和CListHeaderItemUI類增加函數和屬性。


      給CListHeaderUI增加scaleheader屬性,只有scaleheader爲真時纔開啓百分比功能,否則還是根據width屬性來控制寬度


   <Attribute name="scaleheader" default="false" type="BOOL" comment="每個表頭的寬度是否按照百分比來設置"/>


     給CListHeaderItemUI增加scale屬性,設置本子表頭的寬度百分比


   <Attribute name="scale" default="0" type="INT" comment="設置子表頭所佔總表頭的百分比寬度,如40(代表佔40%的寬度)"/>


     給CListHeaderItemUI增加屬性的代碼很簡單,我就不貼了。給CListHeaderUI控件增加SetPos成員函數,寫入如下代碼,加入百分比功能。


void CListHeaderUI::SetPos(RECT rc)
{
	CControlUI::SetPos(rc);
	rc = m_rcItem;

	// Adjust for inset
	rc.left += m_rcInset.left;
	rc.top += m_rcInset.top;
	rc.right -= m_rcInset.right;
	rc.bottom -= m_rcInset.bottom;

	if( m_items.GetSize() == 0) {
		return;
	}


	// Determine the width of elements that are sizeable
	SIZE szAvailable = { rc.right - rc.left, rc.bottom - rc.top };

	int nAdjustables = 0;
	int cxFixed = 0;
	int nEstimateNum = 0;
	for( int it1 = 0; it1 < m_items.GetSize(); it1++ ) {
		CControlUI* pControl = static_cast<CControlUI*>(m_items[it1]);
		if( !pControl->IsVisible() ) continue;
		if( pControl->IsFloat() ) continue;
		SIZE sz = pControl->EstimateSize(szAvailable);
		if( sz.cx == 0 ) {
			nAdjustables++;
		}
		else {
			if( sz.cx < pControl->GetMinWidth() ) sz.cx = pControl->GetMinWidth();
			if( sz.cx > pControl->GetMaxWidth() ) sz.cx = pControl->GetMaxWidth();
		}
		cxFixed += sz.cx +  pControl->GetPadding().left + pControl->GetPadding().right;
		nEstimateNum++;
	}
	cxFixed += (nEstimateNum - 1) * m_iChildPadding;

	int cxExpand = 0;
	int cxNeeded = 0;
	if( nAdjustables > 0 ) cxExpand = MAX(0, (szAvailable.cx - cxFixed) / nAdjustables);
	// Position the elements
	SIZE szRemaining = szAvailable;
	int iPosX = rc.left;

	int iAdjustable = 0;
	int cxFixedRemaining = cxFixed;

	for( int it2 = 0; it2 < m_items.GetSize(); it2++ ) {
		CControlUI* pControl = static_cast<CControlUI*>(m_items[it2]);
		if( !pControl->IsVisible() ) continue;
		if( pControl->IsFloat() ) {
			SetFloatPos(it2);
			continue;
		}
		RECT rcPadding = pControl->GetPadding();
		szRemaining.cx -= rcPadding.left;

		SIZE sz = {0,0};
		if (m_bIsScaleHeader)
		{
			CListHeaderItemUI* pHeaderItem = static_cast<CListHeaderItemUI*>(pControl);
			sz.cx = int(GetWidth() * (float)pHeaderItem->GetScale() / 100);
		}
		else
		{
			sz = pControl->EstimateSize(szRemaining);
		}

		if( sz.cx == 0 ) {
			iAdjustable++;
			sz.cx = cxExpand;
			// Distribute remaining to last element (usually round-off left-overs)
			if( iAdjustable == nAdjustables ) {
				sz.cx = MAX(0, szRemaining.cx - rcPadding.right - cxFixedRemaining);
			}
			if( sz.cx < pControl->GetMinWidth() ) sz.cx = pControl->GetMinWidth();
			if( sz.cx > pControl->GetMaxWidth() ) sz.cx = pControl->GetMaxWidth();
		}
		else {
			if( sz.cx < pControl->GetMinWidth() ) sz.cx = pControl->GetMinWidth();
			if( sz.cx > pControl->GetMaxWidth() ) sz.cx = pControl->GetMaxWidth();

			cxFixedRemaining -= sz.cx;
		}

		sz.cy = pControl->GetFixedHeight();
		if( sz.cy == 0 ) sz.cy = rc.bottom - rc.top - rcPadding.top - rcPadding.bottom;
		if( sz.cy < 0 ) sz.cy = 0;
		if( sz.cy < pControl->GetMinHeight() ) sz.cy = pControl->GetMinHeight();
		if( sz.cy > pControl->GetMaxHeight() ) sz.cy = pControl->GetMaxHeight();

		RECT rcCtrl = { iPosX + rcPadding.left, rc.top + rcPadding.top, iPosX + sz.cx + rcPadding.left + rcPadding.right, rc.top + rcPadding.top + sz.cy};
		pControl->SetPos(rcCtrl);
		iPosX += sz.cx + m_iChildPadding + rcPadding.left + rcPadding.right;
		cxNeeded += sz.cx + rcPadding.left + rcPadding.right;
		szRemaining.cx -= sz.cx + m_iChildPadding + rcPadding.right;
	}
	cxNeeded += (nEstimateNum - 1) * m_iChildPadding;
}


總結:


       完整的代碼可以在我的庫裏下載到:點擊打開鏈接


   Redrain  2015.1.7

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章