UITileLayout.cpp 6.0 KB

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