| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- #include "StdAfx.h"
- #include "UITileLayout.h"
- namespace DuiLib
- {
- IMPLEMENT_DUICONTROL(CTileLayoutUI)
- CTileLayoutUI::CTileLayoutUI() : m_nColumns(1)
- {
- m_szItem.cx = m_szItem.cy = 0;
- }
- LPCTSTR CTileLayoutUI::GetClass() const
- {
- return _T("TileLayoutUI");
- }
- LPVOID CTileLayoutUI::GetInterface(LPCTSTR pstrName)
- {
- if( _tcsicmp(pstrName, DUI_CTR_TILELAYOUT) == 0 ) return static_cast<CTileLayoutUI*>(this);
- return CContainerUI::GetInterface(pstrName);
- }
- SIZE CTileLayoutUI::GetItemSize() const
- {
- if(m_pManager != NULL) return m_pManager->GetDPIObj()->Scale(m_szItem);
- return m_szItem;
- }
- void CTileLayoutUI::SetItemSize(SIZE szItem)
- {
- if( m_szItem.cx != szItem.cx || m_szItem.cy != szItem.cy ) {
- m_szItem = szItem;
- NeedUpdate();
- }
- }
- int CTileLayoutUI::GetColumns() const
- {
- return m_nColumns;
- }
- void CTileLayoutUI::SetColumns(int nCols)
- {
- if( nCols <= 0 ) return;
- m_nColumns = nCols;
- NeedUpdate();
- }
- void CTileLayoutUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue)
- {
- if( _tcsicmp(pstrName, _T("itemsize")) == 0 ) {
- SIZE szItem = { 0 };
- LPTSTR pstr = NULL;
- szItem.cx = _tcstol(pstrValue, &pstr, 10); ASSERT(pstr);
- szItem.cy = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
- SetItemSize(szItem);
- }
- else if( _tcsicmp(pstrName, _T("columns")) == 0 ) SetColumns(_ttoi(pstrValue));
- else CContainerUI::SetAttribute(pstrName, pstrValue);
- }
- void CTileLayoutUI::SetPos(RECT rc, bool bNeedInvalidate)
- {
- CControlUI::SetPos(rc, bNeedInvalidate);
- rc = m_rcItem;
- // 内边距调整
- RECT rcInset = GetInset();
- rc.left += rcInset.left;
- rc.top += rcInset.top;
- rc.right -= rcInset.right;
- rc.bottom -= 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();
- // 确保ItemSize有效,避免除0
- if (szItem.cx <= 0) szItem.cx = 100; // 兜底默认宽度
- if (szItem.cy <= 0) szItem.cy = 100; // 兜底默认高度
- // ========== 核心:固定列数计算(基于固定宽度+水平间距) ==========
- int cxItemWithPadding = szItem.cx + m_iChildPadding; // 单个子控件占宽(含水平间距)
- m_nColumns = (rc.right - rc.left) / cxItemWithPadding;
- if (m_nColumns <= 0) m_nColumns = 1;
- // 滚动条兼容处理
- if (m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible())
- {
- int nTotalWidth = rc.right - rc.left + m_pHorizontalScrollBar->GetScrollRange();
- m_nColumns = nTotalWidth / cxItemWithPadding;
- if (m_nColumns <= 0) m_nColumns = 1;
- }
- // 布局初始化
- int cyNeeded = 0;
- int iCount = 0;
- POINT ptTile = { rc.left, rc.top };
- // 垂直滚动条偏移
- if (m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible())
- ptTile.y -= m_pVerticalScrollBar->GetScrollPos();
- // 水平滚动条偏移
- int iPosX = rc.left;
- if (m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible())
- {
- iPosX -= m_pHorizontalScrollBar->GetScrollPos();
- ptTile.x = iPosX;
- }
- // ========== 遍历子控件:固定宽高+固定间距布局 ==========
- 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;
- }
- // ========== 核心1:固定子控件位置(无动态尺寸计算) ==========
- RECT rcTile = {
- ptTile.x, // 左
- ptTile.y, // 上
- ptTile.x + szItem.cx, // 右(固定宽度)
- ptTile.y + szItem.cy // 下(固定高度)
- };
- // 忽略子控件自身padding,强制使用固定尺寸(如需保留padding可删除此段)
- // RECT rcPadding = pControl->GetPadding();
- // rcTile.left += rcPadding.left;
- // rcTile.right -= rcPadding.right;
- // rcTile.top += rcPadding.top;
- // rcTile.bottom -= rcPadding.bottom;
- // ========== 核心2:强制子控件尺寸为ItemSize(覆盖所有动态计算) ==========
- RECT rcPos = {
- rcTile.left,
- rcTile.top,
- rcTile.left + szItem.cx,
- rcTile.top + szItem.cy
- };
- pControl->SetPos(rcPos, bNeedInvalidate);
- // ========== 核心3:固定间距更新坐标 ==========
- iCount++;
- // 换行:重置X坐标,Y坐标 += 固定高度 + 垂直间距
- if (iCount % m_nColumns == 0)
- {
- ptTile.x = iPosX;
- ptTile.y += szItem.cy + m_iChildPadding; // 垂直间距 = m_iChildPadding
- }
- // 不换行:X坐标 += 固定宽度 + 水平间距
- else
- {
- ptTile.x += szItem.cx + m_iChildPadding; // 水平间距 = m_iChildPadding
- }
- // 更新总高度(用于滚动条)
- cyNeeded = ptTile.y - rc.top + szItem.cy;
- if (m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible())
- cyNeeded += m_pVerticalScrollBar->GetScrollPos();
- }
- // 处理滚动条
- ProcessScrollBar(rc, 0, cyNeeded);
- }
- }
|