UITileLayout.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. #include "stdafx.h"
  2. #include "UITileLayout.h"
  3. namespace DuiLib
  4. {
  5. CTileLayoutUI::CTileLayoutUI() : m_nColumns(1)
  6. {
  7. m_szItem.cx = m_szItem.cy = 0;
  8. }
  9. LPCTSTR CTileLayoutUI::GetClass() const
  10. {
  11. return _T("TileLayoutUI");
  12. }
  13. LPVOID CTileLayoutUI::GetInterface(LPCTSTR pstrName)
  14. {
  15. if( _tcscmp(pstrName, DUI_CTR_TILELAYOUT) == 0 ) return static_cast<CTileLayoutUI*>(this);
  16. return CContainerUI::GetInterface(pstrName);
  17. }
  18. SIZE CTileLayoutUI::GetItemSize() const
  19. {
  20. return m_szItem;
  21. }
  22. void CTileLayoutUI::SetItemSize(SIZE szItem)
  23. {
  24. if( m_szItem.cx != szItem.cx || m_szItem.cy != szItem.cy ) {
  25. m_szItem = szItem;
  26. NeedUpdate();
  27. }
  28. }
  29. int CTileLayoutUI::GetColumns() const
  30. {
  31. return m_nColumns;
  32. }
  33. void CTileLayoutUI::SetColumns(int nCols)
  34. {
  35. if( nCols <= 0 ) return;
  36. m_nColumns = nCols;
  37. NeedUpdate();
  38. }
  39. void CTileLayoutUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue)
  40. {
  41. if( _tcscmp(pstrName, _T("itemsize")) == 0 ) {
  42. SIZE szItem = { 0 };
  43. LPTSTR pstr = NULL;
  44. szItem.cx = _tcstol(pstrValue, &pstr, 10); ASSERT(pstr);
  45. szItem.cy = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
  46. SetItemSize(szItem);
  47. }
  48. else if( _tcscmp(pstrName, _T("columns")) == 0 ) SetColumns(_ttoi(pstrValue));
  49. else CContainerUI::SetAttribute(pstrName, pstrValue);
  50. }
  51. void CTileLayoutUI::SetPos(RECT rc, bool bNeedInvalidate)
  52. {
  53. CControlUI::SetPos(rc, bNeedInvalidate);
  54. rc = m_rcItem;
  55. // Adjust for inset
  56. rc.left += m_rcInset.left;
  57. rc.top += m_rcInset.top;
  58. rc.right -= m_rcInset.right;
  59. rc.bottom -= m_rcInset.bottom;
  60. if( m_items.GetSize() == 0) {
  61. ProcessScrollBar(rc, 0, 0);
  62. return;
  63. }
  64. if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) rc.right -= m_pVerticalScrollBar->GetFixedWidth();
  65. if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) rc.bottom -= m_pHorizontalScrollBar->GetFixedHeight();
  66. // Position the elements
  67. if( m_szItem.cx > 0 ) m_nColumns = (rc.right - rc.left) / m_szItem.cx;
  68. if( m_nColumns == 0 ) m_nColumns = 1;
  69. int cyNeeded = 0;
  70. int cxWidth = (rc.right - rc.left) / m_nColumns;
  71. if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() )
  72. cxWidth = (rc.right - rc.left + m_pHorizontalScrollBar->GetScrollRange() ) / m_nColumns; ;
  73. int cyHeight = 0;
  74. int iCount = 0;
  75. POINT ptTile = { rc.left, rc.top };
  76. if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) {
  77. ptTile.y -= m_pVerticalScrollBar->GetScrollPos();
  78. }
  79. int iPosX = rc.left;
  80. if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) {
  81. iPosX -= m_pHorizontalScrollBar->GetScrollPos();
  82. ptTile.x = iPosX;
  83. }
  84. for( int it1 = 0; it1 < m_items.GetSize(); it1++ ) {
  85. CControlUI* pControl = static_cast<CControlUI*>(m_items[it1]);
  86. if( !pControl->IsVisible() ) continue;
  87. if( pControl->IsFloat() ) {
  88. SetFloatPos(it1);
  89. continue;
  90. }
  91. // Determine size
  92. RECT rcTile = { ptTile.x, ptTile.y, ptTile.x + cxWidth, ptTile.y };
  93. if( (iCount % m_nColumns) == 0 )
  94. {
  95. int iIndex = iCount;
  96. for( int it2 = it1; it2 < m_items.GetSize(); it2++ ) {
  97. CControlUI* pLineControl = static_cast<CControlUI*>(m_items[it2]);
  98. if( !pLineControl->IsVisible() ) continue;
  99. if( pLineControl->IsFloat() ) continue;
  100. RECT rcPadding = pLineControl->GetPadding();
  101. SIZE szAvailable = { rcTile.right - rcTile.left - rcPadding.left - rcPadding.right, 9999 };
  102. if( szAvailable.cx < pControl->GetMinWidth() ) szAvailable.cx = pControl->GetMinWidth();
  103. if( szAvailable.cx > pControl->GetMaxWidth() ) szAvailable.cx = pControl->GetMaxWidth();
  104. SIZE szTile = pLineControl->EstimateSize(szAvailable);
  105. if( szTile.cx == 0 ) szTile.cx = m_szItem.cx;
  106. if( szTile.cy == 0 ) szTile.cy = m_szItem.cy;
  107. if( szTile.cx < pControl->GetMinWidth() ) szTile.cx = pControl->GetMinWidth();
  108. if( szTile.cx > pControl->GetMaxWidth() ) szTile.cx = pControl->GetMaxWidth();
  109. if( szTile.cy < pControl->GetMinHeight() ) szTile.cy = pControl->GetMinHeight();
  110. if( szTile.cy > pControl->GetMaxHeight() ) szTile.cy = pControl->GetMaxHeight();
  111. cyHeight = MAX(cyHeight, szTile.cy + rcPadding.top + rcPadding.bottom);
  112. if( (++iIndex % m_nColumns) == 0) break;
  113. }
  114. }
  115. RECT rcPadding = pControl->GetPadding();
  116. rcTile.left += rcPadding.left;
  117. rcTile.right -= rcPadding.right;
  118. // Set position
  119. rcTile.top = ptTile.y + rcPadding.top;
  120. rcTile.bottom = ptTile.y + cyHeight;
  121. SIZE szAvailable = { rcTile.right - rcTile.left, rcTile.bottom - rcTile.top };
  122. SIZE szTile = pControl->EstimateSize(szAvailable);
  123. if( szTile.cx == 0 ) szTile.cx = m_szItem.cx;
  124. if( szTile.cy == 0 ) szTile.cy = m_szItem.cy;
  125. if( szTile.cx == 0 ) szTile.cx = szAvailable.cx;
  126. if( szTile.cy == 0 ) szTile.cy = szAvailable.cy;
  127. if( szTile.cx < pControl->GetMinWidth() ) szTile.cx = pControl->GetMinWidth();
  128. if( szTile.cx > pControl->GetMaxWidth() ) szTile.cx = pControl->GetMaxWidth();
  129. if( szTile.cy < pControl->GetMinHeight() ) szTile.cy = pControl->GetMinHeight();
  130. if( szTile.cy > pControl->GetMaxHeight() ) szTile.cy = pControl->GetMaxHeight();
  131. RECT rcPos = {(rcTile.left + rcTile.right - szTile.cx) / 2, (rcTile.top + rcTile.bottom - szTile.cy) / 2,
  132. (rcTile.left + rcTile.right - szTile.cx) / 2 + szTile.cx, (rcTile.top + rcTile.bottom - szTile.cy) / 2 + szTile.cy};
  133. pControl->SetPos(rcPos, false);
  134. if( (++iCount % m_nColumns) == 0 ) {
  135. ptTile.x = iPosX;
  136. ptTile.y += cyHeight + m_iChildPadding;
  137. cyHeight = 0;
  138. }
  139. else {
  140. ptTile.x += cxWidth;
  141. }
  142. cyNeeded = rcTile.bottom - rc.top;
  143. if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) cyNeeded += m_pVerticalScrollBar->GetScrollPos();
  144. }
  145. // Process the scrollbar
  146. ProcessScrollBar(rc, 0, cyNeeded);
  147. }
  148. }