mirror of
https://github.com/duilib/duilib.git
synced 2026-10-18 14:50:35 +08:00
02d1ed8832
2、修正了若干bug
342 lines
12 KiB
C++
342 lines
12 KiB
C++
#include "stdafx.h"
|
|
#include "UITileLayout.h"
|
|
|
|
namespace DuiLib
|
|
{
|
|
CTileLayoutUI::CTileLayoutUI() : m_nColumns(1), m_nRows(0), m_nColumnsFixed(0), m_iChildVPadding(0),
|
|
m_bIgnoreItemPadding(true)
|
|
{
|
|
m_szItem.cx = m_szItem.cy = 80;
|
|
}
|
|
|
|
LPCTSTR CTileLayoutUI::GetClass() const
|
|
{
|
|
return DUI_CTR_TILELAYOUT;
|
|
}
|
|
|
|
LPVOID CTileLayoutUI::GetInterface(LPCTSTR pstrName)
|
|
{
|
|
if( _tcscmp(pstrName, DUI_CTR_TILELAYOUT) == 0 ) return static_cast<CTileLayoutUI*>(this);
|
|
return CContainerUI::GetInterface(pstrName);
|
|
}
|
|
|
|
int CTileLayoutUI::GetFixedColumns() const
|
|
{
|
|
return m_nColumnsFixed;
|
|
}
|
|
|
|
void CTileLayoutUI::SetFixedColumns(int iColums)
|
|
{
|
|
if( iColums < 0 ) return;
|
|
m_nColumnsFixed = iColums;
|
|
NeedUpdate();
|
|
}
|
|
|
|
int CTileLayoutUI::GetChildVPadding() const
|
|
{
|
|
return m_iChildVPadding;
|
|
}
|
|
|
|
void CTileLayoutUI::SetChildVPadding(int iPadding)
|
|
{
|
|
m_iChildVPadding = iPadding;
|
|
if (m_iChildVPadding < 0) m_iChildVPadding = 0;
|
|
NeedUpdate();
|
|
}
|
|
|
|
SIZE CTileLayoutUI::GetItemSize() const
|
|
{
|
|
return m_szItem;
|
|
}
|
|
|
|
void CTileLayoutUI::SetItemSize(SIZE szSize)
|
|
{
|
|
if( m_szItem.cx != szSize.cx || m_szItem.cy != szSize.cy ) {
|
|
m_szItem = szSize;
|
|
NeedUpdate();
|
|
}
|
|
}
|
|
|
|
int CTileLayoutUI::GetColumns() const
|
|
{
|
|
return m_nColumns;
|
|
}
|
|
|
|
int CTileLayoutUI::GetRows() const
|
|
{
|
|
return m_nRows;
|
|
}
|
|
|
|
void CTileLayoutUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue)
|
|
{
|
|
if( _tcscmp(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( _tcscmp(pstrName, _T("columns")) == 0 ) SetFixedColumns(_ttoi(pstrValue));
|
|
else if( _tcscmp(pstrName, _T("childvpadding")) == 0 ) SetChildVPadding(_ttoi(pstrValue));
|
|
else CContainerUI::SetAttribute(pstrName, pstrValue);
|
|
}
|
|
|
|
void CTileLayoutUI::SetPos(RECT rc, bool bNeedInvalidate)
|
|
{
|
|
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_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) rc.right -= m_pVerticalScrollBar->GetFixedWidth();
|
|
if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) rc.bottom -= m_pHorizontalScrollBar->GetFixedHeight();
|
|
|
|
if( m_items.GetSize() == 0) {
|
|
ProcessScrollBar(rc, 0, 0);
|
|
return;
|
|
}
|
|
|
|
// Determine the minimum size
|
|
SIZE szAvailable = { rc.right - rc.left, rc.bottom - rc.top };
|
|
if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() )
|
|
szAvailable.cx += m_pHorizontalScrollBar->GetScrollRange();
|
|
if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() )
|
|
szAvailable.cy += m_pVerticalScrollBar->GetScrollRange();
|
|
|
|
int nEstimateNum = 0;
|
|
for( int it = 0; it < m_items.GetSize(); it++ ) {
|
|
CControlUI* pControl = static_cast<CControlUI*>(m_items[it]);
|
|
if( !pControl->IsVisible() ) continue;
|
|
if( pControl->IsFloat() ) continue;
|
|
nEstimateNum++;
|
|
}
|
|
|
|
int cxNeeded = 0;
|
|
int cyNeeded = 0;
|
|
int iChildPadding = m_iChildPadding;
|
|
if (m_nColumnsFixed == 0) {
|
|
if (rc.right - rc.left >= m_szItem.cx) {
|
|
m_nColumns = (rc.right - rc.left)/m_szItem.cx;
|
|
cxNeeded = rc.right - rc.left;
|
|
if (m_nColumns > 1) {
|
|
if (iChildPadding <= 0) {
|
|
iChildPadding = (cxNeeded-m_nColumns*m_szItem.cx)/(m_nColumns-1);
|
|
}
|
|
if (iChildPadding < 0) iChildPadding = 0;
|
|
}
|
|
else {
|
|
iChildPadding = 0;
|
|
}
|
|
}
|
|
else {
|
|
m_nColumns = 1;
|
|
cxNeeded = m_szItem.cx;
|
|
}
|
|
|
|
m_nRows = (nEstimateNum-1)/m_nColumns+1;
|
|
cyNeeded = m_nRows*m_szItem.cy + (m_nRows-1)*m_iChildVPadding;
|
|
}
|
|
else {
|
|
m_nColumns = m_nColumnsFixed;
|
|
if (m_nColumns > 1) {
|
|
if (iChildPadding <= 0) {
|
|
if (m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() && rc.right - rc.left >= m_nColumns*m_szItem.cx) {
|
|
iChildPadding = (rc.right - rc.left-m_nColumns*m_szItem.cx)/(m_nColumns-1);
|
|
}
|
|
else {
|
|
iChildPadding = (szAvailable.cx-m_nColumns*m_szItem.cx)/(m_nColumns-1);
|
|
}
|
|
}
|
|
if (iChildPadding < 0) iChildPadding = 0;
|
|
}
|
|
else iChildPadding = 0;
|
|
|
|
if (nEstimateNum >= m_nColumns) cxNeeded = m_nColumns*m_szItem.cx + (m_nColumns-1)*iChildPadding;
|
|
else cxNeeded = nEstimateNum*m_szItem.cx + (nEstimateNum-1)*iChildPadding;
|
|
m_nRows = (nEstimateNum-1)/m_nColumns+1;
|
|
cyNeeded = m_nRows*m_szItem.cy + (m_nRows-1)*m_iChildVPadding;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
RECT rcPadding = pControl->GetPadding();
|
|
SIZE sz = m_szItem;
|
|
sz.cx -= rcPadding.left + rcPadding.right;
|
|
sz.cy -= rcPadding.top + rcPadding.bottom;
|
|
if( sz.cx > pControl->GetMaxWidth() ) sz.cx = pControl->GetMaxWidth();
|
|
if( sz.cy > pControl->GetMaxHeight() ) sz.cy = pControl->GetMaxHeight();
|
|
if( sz.cx < 0) sz.cx = 0;
|
|
if( sz.cy < 0) sz.cy = 0;
|
|
|
|
UINT iChildAlign = GetChildAlign();
|
|
UINT iChildVAlign = GetChildVAlign();
|
|
int iColumnIndex = it1/m_nColumns;
|
|
int iRowIndex = it1%m_nColumns;
|
|
int iPosX = rc.left + iRowIndex*(m_szItem.cx+iChildPadding);
|
|
if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) {
|
|
iPosX -= m_pHorizontalScrollBar->GetScrollPos();
|
|
}
|
|
int iPosY = rc.top + iColumnIndex*(m_szItem.cy+m_iChildVPadding);
|
|
if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) {
|
|
iPosY -= m_pVerticalScrollBar->GetScrollPos();
|
|
}
|
|
if (iChildAlign == DT_CENTER) {
|
|
if (iChildVAlign == DT_VCENTER) {
|
|
RECT rcCtrl = { iPosX + (m_szItem.cx-sz.cx)/2+rcPadding.left, iPosY + (m_szItem.cy-sz.cy)/2+rcPadding.top, iPosX + (m_szItem.cx-sz.cx)/2 + sz.cx-rcPadding.right, iPosY + (m_szItem.cy-sz.cy)/2 + sz.cy-rcPadding.bottom };
|
|
pControl->SetPos(rcCtrl, false);
|
|
}
|
|
else if (iChildVAlign == DT_BOTTOM) {
|
|
RECT rcCtrl = { iPosX + (m_szItem.cx-sz.cx)/2+rcPadding.left, iPosY + m_szItem.cy - sz.cy+rcPadding.top, iPosX + (m_szItem.cx-sz.cx)/2 + sz.cx-rcPadding.right, iPosY + m_szItem.cy-rcPadding.bottom };
|
|
pControl->SetPos(rcCtrl, false);
|
|
}
|
|
else {
|
|
RECT rcCtrl = { iPosX + (m_szItem.cx-sz.cx)/2+rcPadding.left, iPosY+rcPadding.top, iPosX + (m_szItem.cx-sz.cx)/2 + sz.cx-rcPadding.right, iPosY + sz.cy-rcPadding.bottom };
|
|
pControl->SetPos(rcCtrl, false);
|
|
}
|
|
}
|
|
else if (iChildAlign == DT_RIGHT) {
|
|
if (iChildVAlign == DT_VCENTER) {
|
|
RECT rcCtrl = { iPosX + m_szItem.cx - sz.cx+rcPadding.left, iPosY + (m_szItem.cy-sz.cy)/2+rcPadding.top, iPosX + m_szItem.cx-rcPadding.right, iPosY + (m_szItem.cy-sz.cy)/2 + sz.cy-rcPadding.bottom };
|
|
pControl->SetPos(rcCtrl, false);
|
|
}
|
|
else if (iChildVAlign == DT_BOTTOM) {
|
|
RECT rcCtrl = { iPosX + m_szItem.cx - sz.cx+rcPadding.left, iPosY + m_szItem.cy - sz.cy+rcPadding.top, iPosX + m_szItem.cx-rcPadding.right, iPosY + m_szItem.cy-rcPadding.bottom };
|
|
pControl->SetPos(rcCtrl, false);
|
|
}
|
|
else {
|
|
RECT rcCtrl = { iPosX + m_szItem.cx - sz.cx+rcPadding.left, iPosY+rcPadding.top, iPosX + m_szItem.cx-rcPadding.right, iPosY + sz.cy-rcPadding.bottom };
|
|
pControl->SetPos(rcCtrl, false);
|
|
}
|
|
}
|
|
else {
|
|
if (iChildVAlign == DT_VCENTER) {
|
|
RECT rcCtrl = { iPosX+rcPadding.left, iPosY + (m_szItem.cy-sz.cy)/2+rcPadding.top, iPosX + sz.cx-rcPadding.right, iPosY + (m_szItem.cy-sz.cy)/2 + sz.cy-rcPadding.bottom };
|
|
pControl->SetPos(rcCtrl, false);
|
|
}
|
|
else if (iChildVAlign == DT_BOTTOM) {
|
|
RECT rcCtrl = { iPosX+rcPadding.left, iPosY + m_szItem.cy - sz.cy+rcPadding.top, iPosX + sz.cx-rcPadding.right, iPosY + m_szItem.cy-rcPadding.bottom };
|
|
pControl->SetPos(rcCtrl, false);
|
|
}
|
|
else {
|
|
RECT rcCtrl = { iPosX+rcPadding.left, iPosY+rcPadding.top, iPosX + sz.cx-rcPadding.right, iPosY + sz.cy-rcPadding.bottom };
|
|
pControl->SetPos(rcCtrl, false);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Process the scrollbar
|
|
ProcessScrollBar(rc, cxNeeded, cyNeeded);
|
|
|
|
|
|
|
|
// // Position the elements
|
|
// if( m_szItem.cx > 0 ) {
|
|
// m_nColumns = (rc.right - rc.left) / m_szItem.cx;
|
|
// if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() )
|
|
// m_nColumns = (rc.right - rc.left + m_pHorizontalScrollBar->GetScrollRange() ) / m_szItem.cx;
|
|
// }
|
|
|
|
// if( m_nColumns == 0 ) m_nColumns = 1;
|
|
|
|
// int cyNeeded = 0;
|
|
// int cxWidth = (rc.right - rc.left) / m_nColumns;
|
|
// if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() )
|
|
// cxWidth = (rc.right - rc.left + m_pHorizontalScrollBar->GetScrollRange() ) / m_nColumns;
|
|
|
|
// int cyHeight = 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;
|
|
// }
|
|
|
|
// // Determine size
|
|
// RECT rcTile = { ptTile.x, ptTile.y, ptTile.x + cxWidth, ptTile.y };
|
|
// if( (iCount % m_nColumns) == 0 )
|
|
// {
|
|
// int iIndex = iCount;
|
|
// for( int it2 = it1; it2 < m_items.GetSize(); it2++ ) {
|
|
// 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 };
|
|
|
|
// if( szAvailable.cx < pControl->GetMinWidth() ) szAvailable.cx = pControl->GetMinWidth();
|
|
// if( szAvailable.cx > pControl->GetMaxWidth() ) szAvailable.cx = pControl->GetMaxWidth();
|
|
|
|
// SIZE szTile = pLineControl->EstimateSize(szAvailable);
|
|
// if( szTile.cx == 0 ) szTile.cx = m_szItem.cx;
|
|
// if( szTile.cy == 0 ) szTile.cy = m_szItem.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();
|
|
|
|
// cyHeight = MAX(cyHeight, szTile.cy + rcPadding.top + rcPadding.bottom);
|
|
// if( (++iIndex % m_nColumns) == 0) break;
|
|
// }
|
|
// }
|
|
|
|
// RECT rcPadding = pControl->GetPadding();
|
|
|
|
// rcTile.left += rcPadding.left;
|
|
// rcTile.right -= rcPadding.right;
|
|
|
|
// // Set position
|
|
// rcTile.top = ptTile.y + rcPadding.top;
|
|
// rcTile.bottom = ptTile.y + cyHeight;
|
|
|
|
// SIZE szAvailable = { rcTile.right - rcTile.left, rcTile.bottom - rcTile.top };
|
|
// SIZE szTile = pControl->EstimateSize(szAvailable);
|
|
// if( szTile.cx == 0 ) szTile.cx = m_szItem.cx;
|
|
// if( szTile.cy == 0 ) szTile.cy = m_szItem.cy;
|
|
// 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, false);
|
|
|
|
// if( (++iCount % m_nColumns) == 0 ) {
|
|
// ptTile.x = iPosX;
|
|
// ptTile.y += cyHeight + iChildPadding;
|
|
// cyHeight = 0;
|
|
// }
|
|
// else {
|
|
// ptTile.x += cxWidth;
|
|
// }
|
|
// cyNeeded = rcTile.bottom - rc.top;
|
|
// if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) cyNeeded += m_pVerticalScrollBar->GetScrollPos();
|
|
// }
|
|
|
|
// // Process the scrollbar
|
|
// ProcessScrollBar(rc, 0, cyNeeded);
|
|
}
|
|
}
|