Duilib中的TitleLayoutUI控件修改成横向滑动展示(以Troy的DuiLib_Ultimate为例)

19 篇文章 0 订阅
9 篇文章 1 订阅

Duilib中的TitleLayoutUI默认是竖向滚动展示,以Troy的DuiLib_Ultimate为例,如图显示

现在想做成横向滑动显示,如下图:

 

下面说一下修改的方法,其实很简单,就是将CTileLayoutUI::SetPos函数中的所有的x改成y,y改成x;top和bottom改成left和right,left和right改成top和bottom;Hor改成Ver,Ver改成Hor就可以了,因为源码已经写的很好了。

下面是修改后的代码:



//头文件
#pragma once


class CMyTileLayoutUI :public CTileLayoutUI {
public:
	CMyTileLayoutUI();
	virtual ~CMyTileLayoutUI();
	virtual void SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue);
	virtual void SetPos(RECT rc, bool bNeedInvalidate = true);
	void SetHSLayout(bool bHSLayout);//设置横线滑动
protected:
	virtual void SetPos_hor(RECT rc, bool bNeedInvalidate = true);
protected:
	int m_nRows;//行数
	bool m_bHSLayout;//默认false
};


//源文件
#include "stdafx.h"
#include "UIMyTileLayout.h"

CMyTileLayoutUI::CMyTileLayoutUI():m_nRows(1),m_bHSLayout(false) {}

CMyTileLayoutUI::~CMyTileLayoutUI() {}

void CMyTileLayoutUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue) {
	if (_tcscmp(pstrName, _T("hslayout")) == 0)
		SetHSLayout(_tcscmp(pstrValue, _T("true")) == 0);
	else CTileLayoutUI::SetAttribute(pstrName, pstrValue);
}

void CMyTileLayoutUI::SetHSLayout(bool bHSLayout) {
	m_bHSLayout = bHSLayout;
}

void CMyTileLayoutUI::SetPos(RECT rc, bool bNeedInvalidate/* = true*/) {
	if (m_bHSLayout) {
		SetPos_hor(rc, bNeedInvalidate);
	}
	else {
		CTileLayoutUI::SetPos(rc, bNeedInvalidate);
	}
}

void CMyTileLayoutUI::SetPos_hor(RECT rc, bool bNeedInvalidate/* = true*/){
	CControlUI::SetPos(rc, bNeedInvalidate);
	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) {
		ProcessScrollBar(rc, 0, 0);
		return;
	}

	if (m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible()) rc.right -= m_pVerticalScrollBar->GetFixedWidth();
	if (m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible()) rc.bottom -= m_pHorizontalScrollBar->GetFixedHeight();

	SIZE szItem = GetItemSize();
	// Position the elements
	if (szItem.cy > 0) m_nRows = (rc.bottom - rc.top) / szItem.cy;//求行数
	if (m_nRows == 0) m_nRows = 1;

	int cxNeeded = 0;
	int cyHeight = (rc.bottom - rc.top) / m_nRows;
	if (m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible())
		cyHeight = (rc.bottom - rc.top + m_pVerticalScrollBar->GetScrollRange()) / m_nRows;

	int cxWidth = 0;
	int iCount = 0;
	POINT ptTile = { rc.left, rc.top };
	if (m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible()) {
		ptTile.x -= m_pHorizontalScrollBar->GetScrollPos();
	}
	int iPosY = rc.top;
	if (m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible()) {
		iPosY -= m_pVerticalScrollBar->GetScrollPos();
		ptTile.y = iPosY;
	}

	for (int it1 = 0; it1 < m_items.GetSize(); it1++) {
		CControlUI* pControl = static_cast<CControlUI*>(m_items[it1]);
		if (!pControl->IsVisible()) continue;
		if (pControl->IsFloat()) {
			SetFloatPos(it1);
			continue;
		}

		// Determine size
		RECT rcTile = { ptTile.x, ptTile.y, ptTile.x, ptTile.y + cyHeight };
		if ((iCount % m_nRows) == 0)
		{
			int iIndex = iCount;
			for (int it2 = it1; it2 < m_items.GetSize(); it2++) { //一列item中找到width最大的那个,并记录width,以该值作为这一列的宽度
				CControlUI* pLineControl = static_cast<CControlUI*>(m_items[it2]);
				if (!pLineControl->IsVisible()) continue;
				if (pLineControl->IsFloat()) continue;

				RECT rcPadding = pLineControl->GetPadding();
				//					SIZE szAvailable = { rcTile.right - rcTile.left - rcPadding.left - rcPadding.right, 9999 };
				SIZE szAvailable = { 9999, rcTile.bottom - rcTile.top - rcPadding.top - rcPadding.bottom };
				if (iIndex == iCount || (iIndex + 1) % m_nRows == 0) {
					szAvailable.cy -= m_iChildPadding / 2;
				}
				else {
					szAvailable.cy -= m_iChildPadding;
				}

				if (szAvailable.cy < pControl->GetMinHeight()) szAvailable.cy = pControl->GetMinHeight();
				if (szAvailable.cy > pControl->GetMaxHeight()) szAvailable.cy = pControl->GetMaxHeight();

				SIZE szTile = pLineControl->EstimateSize(szAvailable);
				if (szTile.cx < pControl->GetMinWidth()) szTile.cx = pControl->GetMinWidth();
				if (szTile.cx > pControl->GetMaxWidth()) szTile.cx = pControl->GetMaxWidth();
				if (szTile.cy < pControl->GetMinHeight()) szTile.cy = pControl->GetMinHeight();
				if (szTile.cy > pControl->GetMaxHeight()) szTile.cy = pControl->GetMaxHeight();

				cxWidth = MAX(cxWidth, szTile.cx + rcPadding.left + rcPadding.right);
				if ((++iIndex % m_nRows) == 0) break;
			}
		}

		RECT rcPadding = pControl->GetPadding();

		rcTile.top += rcPadding.top + m_iChildPadding / 2;
		rcTile.bottom -= rcPadding.bottom + m_iChildPadding / 2;
		if ((iCount % m_nRows) == 0) {
			rcTile.top -= m_iChildPadding / 2;
		}

		if (((iCount + 1) % m_nRows) == 0) {
			rcTile.bottom += m_iChildPadding / 2;
		}

		// Set position
		rcTile.left = ptTile.x + rcPadding.left;
		rcTile.right = ptTile.x + cxWidth;

		SIZE szAvailable = { rcTile.right - rcTile.left, rcTile.bottom - rcTile.top };
		SIZE szTile = pControl->EstimateSize(szAvailable);
		if (szTile.cx == 0) szTile.cx = szAvailable.cx;
		if (szTile.cy == 0) szTile.cy = szAvailable.cy;
		if (szTile.cx < pControl->GetMinWidth()) szTile.cx = pControl->GetMinWidth();
		if (szTile.cx > pControl->GetMaxWidth()) szTile.cx = pControl->GetMaxWidth();
		if (szTile.cy < pControl->GetMinHeight()) szTile.cy = pControl->GetMinHeight();
		if (szTile.cy > pControl->GetMaxHeight()) szTile.cy = pControl->GetMaxHeight();
		RECT rcPos = { (rcTile.left + rcTile.right - szTile.cx) / 2, (rcTile.top + rcTile.bottom - szTile.cy) / 2,
			(rcTile.left + rcTile.right - szTile.cx) / 2 + szTile.cx, (rcTile.top + rcTile.bottom - szTile.cy) / 2 + szTile.cy };
		pControl->SetPos(rcPos);

		if ((++iCount % m_nRows) == 0) {
			ptTile.y = iPosY;
			ptTile.x += cxWidth + m_iChildPadding;
			cxWidth = 0;
		}
		else {
			ptTile.y += cyHeight;
		}
		cxNeeded = rcTile.right - rc.left;
		if (m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible()) cxNeeded += m_pHorizontalScrollBar->GetScrollPos();
	}

	ProcessScrollBar(rc, cxNeeded, 0);
}

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值