XTPMarkupGrid.cpp
上传用户:szled88
上传日期:2015-04-09
资源大小:43957k
文件大小:27k
源码类别:

对话框与窗口

开发平台:

Visual C++

  1. // XTPMarkupGrid.cpp: implementation of the CXTPMarkupGrid class.
  2. //
  3. // This file is a part of the XTREME TOOLKIT PRO MFC class library.
  4. // (c)1998-2008 Codejock Software, All Rights Reserved.
  5. //
  6. // THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
  7. // RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
  8. // CONSENT OF CODEJOCK SOFTWARE.
  9. //
  10. // THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
  11. // IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
  12. // YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
  13. // SINGLE COMPUTER.
  14. //
  15. // CONTACT INFORMATION:
  16. // support@codejock.com
  17. // http://www.codejock.com
  18. //
  19. /////////////////////////////////////////////////////////////////////////////
  20. #include "stdafx.h"
  21. #include "Common/XTPVc80Helpers.h"
  22. #include "XTPMarkupGrid.h"
  23. #include "XTPMarkupBuilder.h"
  24. #ifdef _DEBUG
  25. #undef THIS_FILE
  26. static char THIS_FILE[]=__FILE__;
  27. #define new DEBUG_NEW
  28. #endif
  29. //////////////////////////////////////////////////////////////////////////
  30. // CXTPMarkupGridLength
  31. IMPLEMENT_MARKUPCLASS(NULL, CXTPMarkupGridLength, CXTPMarkupObject);
  32. void CXTPMarkupGridLength::RegisterMarkupClass()
  33. {
  34. }
  35. CXTPMarkupGridLength::CXTPMarkupGridLength(double nValue /* = 0 */, CXTPMarkupGridLength::GridUnitType type /* = xtpMarkupGridUnitPixel */)
  36. {
  37. m_nValue = nValue;
  38. m_type = type;
  39. }
  40. CXTPMarkupObject* CXTPMarkupGridLength::ConvertFrom(CXTPMarkupObject* pObject) const
  41. {
  42. if (IsStringObject(pObject))
  43. {
  44. LPCWSTR lpszValue = *((CXTPMarkupString*)pObject);
  45. int nLength = ((CXTPMarkupString*)pObject)->GetLength();
  46. if (nLength < 1)
  47. return NULL;
  48. if (nLength == 4 && _wcsicmp(lpszValue, L"Auto") == 0)
  49. {
  50. return new CXTPMarkupGridLength(1, unitTypeAuto);
  51. }
  52. float fValue = 0;
  53. WSCANF_S(lpszValue, L"%f", &fValue);
  54. if (lpszValue[nLength - 1] == '*')
  55. {
  56. return new CXTPMarkupGridLength(nLength == 1 ? 1 : fValue, unitTypeStar);
  57. }
  58. return new CXTPMarkupGridLength(fValue);
  59. }
  60. return NULL;
  61. }
  62. //////////////////////////////////////////////////////////////////////////
  63. // CXTPMarkupDefinitionBase
  64. CXTPMarkupDefinitionBase::CXTPMarkupDefinitionBase(BOOL bIsColumnDefinition)
  65. {
  66. m_bIsColumnDefinition = bIsColumnDefinition;
  67. m_nMinSize = 0;
  68. m_nSizeType = 0;
  69. m_nMeasureSize = 0;
  70. }
  71. void CXTPMarkupDefinitionBase::OnBeforeLayout()
  72. {
  73. m_nSizeType = 0;
  74. m_nMinSize = 0;
  75. m_nMeasureSize = 0;
  76. }
  77. void CXTPMarkupDefinitionBase::UpdateMinSize(int nMinSize)
  78. {
  79. m_nMinSize = max(m_nMinSize, nMinSize);
  80. }
  81. int CXTPMarkupDefinitionBase::GetUserMinSize() const
  82. {
  83. CXTPMarkupInt* pMinValue = MARKUP_STATICCAST(CXTPMarkupInt, GetValue(m_bIsColumnDefinition ? CXTPMarkupColumnDefinition::m_pMinWidthProperty : CXTPMarkupRowDefinition::m_pMinHeightProperty));
  84. return pMinValue != NULL ? (int)*pMinValue : 0;
  85. }
  86. int CXTPMarkupDefinitionBase::GetUserMaxSize() const
  87. {
  88. CXTPMarkupInt* pMaxValue = MARKUP_STATICCAST(CXTPMarkupInt, GetValue(m_bIsColumnDefinition ? CXTPMarkupColumnDefinition::m_pMaxWidthProperty : CXTPMarkupRowDefinition::m_pMaxHeightProperty));
  89. return pMaxValue != NULL ? (int)*pMaxValue : INT_MAX;
  90. }
  91. CXTPMarkupGridLength* CXTPMarkupDefinitionBase::GetUserSize() const
  92. {
  93. CXTPMarkupGridLength* pValue = MARKUP_STATICCAST(CXTPMarkupGridLength, GetValue(m_bIsColumnDefinition ? CXTPMarkupColumnDefinition::m_pWidthProperty : CXTPMarkupRowDefinition::m_pHeightProperty));
  94. ASSERT(pValue);
  95. return pValue;
  96. }
  97. //////////////////////////////////////////////////////////////////////////
  98. // CXTPMarkupColumnDefinition
  99. CXTPMarkupDependencyProperty* CXTPMarkupColumnDefinition::m_pWidthProperty = NULL;
  100. CXTPMarkupDependencyProperty* CXTPMarkupColumnDefinition::m_pMinWidthProperty = NULL;
  101. CXTPMarkupDependencyProperty* CXTPMarkupColumnDefinition::m_pMaxWidthProperty = NULL;
  102. IMPLEMENT_MARKUPCLASS(L"ColumnDefinition", CXTPMarkupColumnDefinition, CXTPMarkupObject);
  103. void CXTPMarkupColumnDefinition::RegisterMarkupClass()
  104. {
  105. m_pWidthProperty = CXTPMarkupDependencyProperty::Register(L"Width", MARKUP_TYPE(CXTPMarkupGridLength), MARKUP_TYPE(CXTPMarkupColumnDefinition),
  106. new CXTPMarkupPropertyMetadata(new CXTPMarkupGridLength(1, CXTPMarkupGridLength::unitTypeStar)));
  107. m_pMinWidthProperty = CXTPMarkupDependencyProperty::Register(L"MinWidth", MARKUP_TYPE(CXTPMarkupInt), MARKUP_TYPE(CXTPMarkupColumnDefinition));
  108. m_pMaxWidthProperty = CXTPMarkupDependencyProperty::Register(L"MaxWidth", MARKUP_TYPE(CXTPMarkupInt), MARKUP_TYPE(CXTPMarkupColumnDefinition));
  109. }
  110. CXTPMarkupColumnDefinition::CXTPMarkupColumnDefinition()
  111. : CXTPMarkupDefinitionBase(TRUE)
  112. {
  113. }
  114. //////////////////////////////////////////////////////////////////////////
  115. // CXTPMarkupRowDefinition
  116. CXTPMarkupDependencyProperty* CXTPMarkupRowDefinition::m_pHeightProperty = NULL;
  117. CXTPMarkupDependencyProperty* CXTPMarkupRowDefinition::m_pMinHeightProperty = NULL;
  118. CXTPMarkupDependencyProperty* CXTPMarkupRowDefinition::m_pMaxHeightProperty = NULL;
  119. IMPLEMENT_MARKUPCLASS(L"RowDefinition", CXTPMarkupRowDefinition, CXTPMarkupObject);
  120. void CXTPMarkupRowDefinition::RegisterMarkupClass()
  121. {
  122. m_pHeightProperty = CXTPMarkupDependencyProperty::Register(L"Height", MARKUP_TYPE(CXTPMarkupGridLength), MARKUP_TYPE(CXTPMarkupRowDefinition),
  123. new CXTPMarkupPropertyMetadata(new CXTPMarkupGridLength(1, CXTPMarkupGridLength::unitTypeStar)));
  124. m_pMinHeightProperty = CXTPMarkupDependencyProperty::Register(L"MinHeight", MARKUP_TYPE(CXTPMarkupInt), MARKUP_TYPE(CXTPMarkupRowDefinition));
  125. m_pMaxHeightProperty = CXTPMarkupDependencyProperty::Register(L"MaxHeight", MARKUP_TYPE(CXTPMarkupInt), MARKUP_TYPE(CXTPMarkupRowDefinition));
  126. }
  127. CXTPMarkupRowDefinition::CXTPMarkupRowDefinition()
  128. : CXTPMarkupDefinitionBase(FALSE)
  129. {
  130. }
  131. //////////////////////////////////////////////////////////////////////////
  132. // CXTPMarkupDefinitionCollection
  133. IMPLEMENT_MARKUPCLASS(NULL, CXTPMarkupDefinitionCollection, CXTPMarkupCollection);
  134. void CXTPMarkupDefinitionCollection::RegisterMarkupClass()
  135. {
  136. }
  137. CXTPMarkupDefinitionCollection::CXTPMarkupDefinitionCollection()
  138. {
  139. }
  140. IMPLEMENT_MARKUPCLASS(NULL, CXTPMarkupRowDefinitionCollection, CXTPMarkupDefinitionCollection);
  141. void CXTPMarkupRowDefinitionCollection::RegisterMarkupClass()
  142. {
  143. }
  144. CXTPMarkupRowDefinitionCollection::CXTPMarkupRowDefinitionCollection()
  145. {
  146. m_pElementType = MARKUP_TYPE(CXTPMarkupRowDefinition);
  147. }
  148. IMPLEMENT_MARKUPCLASS(NULL, CXTPMarkupColumnDefinitionCollection, CXTPMarkupDefinitionCollection);
  149. void CXTPMarkupColumnDefinitionCollection::RegisterMarkupClass()
  150. {
  151. }
  152. CXTPMarkupColumnDefinitionCollection::CXTPMarkupColumnDefinitionCollection()
  153. {
  154. m_pElementType = MARKUP_TYPE(CXTPMarkupColumnDefinition);
  155. }
  156. //////////////////////////////////////////////////////////////////////
  157. // Construction/Destruction
  158. //////////////////////////////////////////////////////////////////////
  159. CXTPMarkupDependencyProperty* CXTPMarkupGrid::m_pColumnDefinitionsProperty = NULL;
  160. CXTPMarkupDependencyProperty* CXTPMarkupGrid::m_pRowDefinitionsProperty = NULL;
  161. CXTPMarkupDependencyProperty* CXTPMarkupGrid::m_pColumnProperty = NULL;
  162. CXTPMarkupDependencyProperty* CXTPMarkupGrid::m_pRowProperty = NULL;
  163. IMPLEMENT_MARKUPCLASS(L"Grid", CXTPMarkupGrid, CXTPMarkupPanel)
  164. void CXTPMarkupGrid::RegisterMarkupClass()
  165. {
  166. m_pColumnDefinitionsProperty = CXTPMarkupDependencyProperty::Register(L"ColumnDefinitions", MARKUP_TYPE(CXTPMarkupColumnDefinitionCollection), MARKUP_TYPE(CXTPMarkupGrid));
  167. m_pRowDefinitionsProperty = CXTPMarkupDependencyProperty::Register(L"RowDefinitions", MARKUP_TYPE(CXTPMarkupRowDefinitionCollection), MARKUP_TYPE(CXTPMarkupGrid));
  168. m_pColumnProperty = CXTPMarkupDependencyProperty::RegisterAttached(L"Column", MARKUP_TYPE(CXTPMarkupInt), MARKUP_TYPE(CXTPMarkupGrid),
  169. new CXTPMarkupPropertyMetadata(NULL, &CXTPMarkupGrid::OnCellAttachedPropertyChanged));
  170. m_pRowProperty = CXTPMarkupDependencyProperty::RegisterAttached(L"Row", MARKUP_TYPE(CXTPMarkupInt), MARKUP_TYPE(CXTPMarkupGrid),
  171. new CXTPMarkupPropertyMetadata(NULL, &CXTPMarkupGrid::OnCellAttachedPropertyChanged));
  172. }
  173. CXTPMarkupGrid::CXTPMarkupGrid()
  174. {
  175. m_pRowDefinitions = new CXTPMarkupRowDefinitionCollection();
  176. m_pRowDefinitions->SetLogicalParent(this);
  177. m_pColumnDefinitions = new CXTPMarkupColumnDefinitionCollection();
  178. m_pColumnDefinitions->SetLogicalParent(this);
  179. m_pCellCachesCollection = NULL;
  180. m_pDefinitionsU = NULL;
  181. m_pDefinitionsV = NULL;
  182. }
  183. CXTPMarkupGrid::~CXTPMarkupGrid()
  184. {
  185. MARKUP_RELEASE(m_pColumnDefinitions);
  186. MARKUP_RELEASE(m_pRowDefinitions);
  187. SAFE_DELETE_AR(m_pCellCachesCollection);
  188. MARKUP_RELEASE(m_pDefinitionsU);
  189. MARKUP_RELEASE(m_pDefinitionsV);
  190. }
  191. void CXTPMarkupGrid::OnCellAttachedPropertyChanged(CXTPMarkupObject* d, CXTPMarkupPropertyChangedEventArgs* /*e*/)
  192. {
  193. CXTPMarkupUIElement* pVisual = MARKUP_DYNAMICCAST(CXTPMarkupUIElement, d);
  194. if (!pVisual)
  195. return;
  196. CXTPMarkupGrid* pGrid = MARKUP_DYNAMICCAST(CXTPMarkupGrid, pVisual->GetVisualParent());
  197. if (!pGrid)
  198. return;
  199. pGrid->InvalidateMeasure();
  200. }
  201. int CXTPMarkupGrid::GetColumn(CXTPMarkupUIElement* pElement)
  202. {
  203. CXTPMarkupInt* pColumn = MARKUP_STATICCAST(CXTPMarkupInt, pElement->GetValue(m_pColumnProperty));
  204. return pColumn != NULL ? (int)*pColumn : 0;
  205. }
  206. int CXTPMarkupGrid::GetRow(CXTPMarkupUIElement* pElement)
  207. {
  208. CXTPMarkupInt* pRow = MARKUP_STATICCAST(CXTPMarkupInt, pElement->GetValue(m_pRowProperty));
  209. return pRow != NULL ? (int)*pRow : 0;
  210. }
  211. void CXTPMarkupGrid::SetColumn(CXTPMarkupUIElement* pElement, int nColumn)
  212. {
  213. pElement->SetValue(m_pColumnProperty, new CXTPMarkupInt(nColumn));
  214. }
  215. void CXTPMarkupGrid::SetRow(CXTPMarkupUIElement* pElement, int nRow)
  216. {
  217. pElement->SetValue(m_pRowProperty, new CXTPMarkupInt(nRow));
  218. }
  219. int CXTPMarkupGrid::GetColumnSpan(CXTPMarkupUIElement* /*pElement*/)
  220. {
  221. return 1;
  222. }
  223. int CXTPMarkupGrid::GetRowSpan(CXTPMarkupUIElement* /*pElement*/)
  224. {
  225. return 1;
  226. }
  227. void CXTPMarkupGrid::SetPropertyObject(CXTPMarkupBuilder* pBuilder, CXTPMarkupDependencyProperty* pProperty, CXTPMarkupObject* pValue)
  228. {
  229. if (pProperty == m_pColumnDefinitionsProperty)
  230. {
  231. if (!pValue || !pValue->IsKindOf(MARKUP_TYPE(CXTPMarkupColumnDefinitionCollection)))
  232. {
  233. pBuilder->ThrowBuilderException(_T("CXTPMarkupColumnDefinitionCollection class expected"));
  234. }
  235. MARKUP_RELEASE(m_pColumnDefinitions);
  236. m_pColumnDefinitions = (CXTPMarkupColumnDefinitionCollection*)pValue;
  237. m_pColumnDefinitions->SetLogicalParent(this);
  238. }
  239. else if (pProperty == m_pRowDefinitionsProperty)
  240. {
  241. if (!pValue || !pValue->IsKindOf(MARKUP_TYPE(CXTPMarkupRowDefinitionCollection)))
  242. {
  243. pBuilder->ThrowBuilderException(_T("CXTPMarkupRowDefinitionCollection class expected"));
  244. }
  245. MARKUP_RELEASE(m_pRowDefinitions);
  246. m_pRowDefinitions = (CXTPMarkupRowDefinitionCollection*)pValue;
  247. m_pRowDefinitions->SetLogicalParent(this);
  248. }
  249. else
  250. {
  251. CXTPMarkupPanel::SetPropertyObject(pBuilder, pProperty, pValue);
  252. }
  253. }
  254. AFX_INLINE BOOL IsPositiveInfinity(int size) {
  255. return size > 32000;
  256. }
  257. AFX_INLINE BOOL IsNan(int nSize) {
  258. return nSize == INT_MAX;
  259. }
  260. void CXTPMarkupGrid::ValidateDefinitionsLayout(CXTPMarkupDefinitionCollection* pDefinitions, BOOL bTreatStarAsAuto)
  261. {
  262. for (int i = 0; i < pDefinitions->GetCount(); i++)
  263. {
  264. CXTPMarkupDefinitionBase* pDefinition = pDefinitions->GetItem(i);
  265. pDefinition->OnBeforeLayout();
  266. int nUserMinSize = pDefinition->GetUserMinSize();
  267. int nUserMaxSize = pDefinition->GetUserMaxSize();
  268. int nPositiveInfinity = INT_MAX;
  269. switch (pDefinition->GetUserSize()->GetUnitType())
  270. {
  271. case CXTPMarkupGridLength::unitTypeAuto:
  272. pDefinition->m_nSizeType = sizeTypeAuto;
  273. break;
  274. case  CXTPMarkupGridLength::unitTypePixel:
  275. pDefinition->m_nSizeType = sizeTypePixel;
  276. nPositiveInfinity = (int)pDefinition->GetUserSize()->GetValue();
  277. nUserMinSize = max(nUserMinSize, min(nPositiveInfinity, nUserMaxSize));
  278. break;
  279. case CXTPMarkupGridLength::unitTypeStar:
  280. pDefinition->m_nSizeType = bTreatStarAsAuto ? sizeTypeAuto : sizeTypeStar;
  281. break;
  282.    }
  283. pDefinition->UpdateMinSize(nUserMinSize);
  284. pDefinition->m_nMeasureSize = max(nUserMinSize, min(nPositiveInfinity, nUserMaxSize));
  285. }
  286. }
  287. int CXTPMarkupGrid::GetLengthTypeForRange(CXTPMarkupDefinitionCollection* pDefinitions, int start, int count)
  288. {
  289. ASSERT(pDefinitions->GetCount() > 0);
  290. int nSizeType = sizeTypeNone;
  291. for (int i = start; i < start + count; i++)
  292. {
  293. nSizeType = (nSizeType | pDefinitions->GetItem(i)->m_nSizeType);
  294. }
  295. return nSizeType;
  296. }
  297. BOOL CXTPMarkupGrid::CELLCACHE::IsStarU() const
  298. {
  299. return nSizeTypeU & CXTPMarkupGrid::sizeTypeStar;
  300. }
  301. BOOL CXTPMarkupGrid::CELLCACHE::IsStarV() const
  302. {
  303. return nSizeTypeV & CXTPMarkupGrid::sizeTypeStar;
  304. }
  305. BOOL CXTPMarkupGrid::CELLCACHE::IsAutoU() const
  306. {
  307. return nSizeTypeU & CXTPMarkupGrid::sizeTypeAuto;
  308. }
  309. BOOL CXTPMarkupGrid::CELLCACHE::IsAutoV() const
  310. {
  311. return nSizeTypeV & CXTPMarkupGrid::sizeTypeAuto;
  312. }
  313. void CXTPMarkupGrid::ValidateCells()
  314. {
  315. SAFE_DELETE_AR(m_pCellCachesCollection);
  316. m_pCellCachesCollection = new CELLCACHE[GetChildren()->GetCount()];
  317. m_nCellGroup[0] = INT_MAX;
  318. m_nCellGroup[1] = INT_MAX;
  319. m_nCellGroup[2] = INT_MAX;
  320. m_nCellGroup[3] = INT_MAX;
  321. BOOL flag = FALSE;
  322. BOOL flag2 = FALSE;
  323. BOOL flag3 = FALSE;
  324. for (int i = GetChildren()->GetCount() - 1; i >= 0; i--)
  325. {
  326. CXTPMarkupUIElement* pElement = GetChildren()->GetItem(i);
  327. if (!pElement)
  328. continue;
  329. CELLCACHE& cache = m_pCellCachesCollection[i];
  330. cache.nColumnIndex = min(GetColumn(pElement), m_pDefinitionsU->GetCount() - 1);
  331. cache.nRowIndex = min(GetRow(pElement), m_pDefinitionsV->GetCount() - 1);
  332. cache.nColumnSpan = min(GetColumnSpan(pElement), m_pDefinitionsU->GetCount() - cache.nColumnIndex);
  333. cache.nRowSpan = min(GetRowSpan(pElement),  m_pDefinitionsV->GetCount() - cache.nRowIndex);
  334. cache.nSizeTypeU = GetLengthTypeForRange(m_pDefinitionsU, cache.nColumnIndex, cache.nColumnSpan);
  335. cache.nSizeTypeV = GetLengthTypeForRange(m_pDefinitionsV, cache.nRowIndex, cache.nRowSpan);
  336. flag |= cache.IsStarU();
  337. flag2 |= cache.IsStarV();
  338. if (!cache.IsStarV())
  339. {
  340. if (!cache.IsStarU())
  341. {
  342. cache.nNext = m_nCellGroup[0];
  343. m_nCellGroup[0] = i;
  344. }
  345. else
  346. {
  347. cache.nNext = m_nCellGroup[2];
  348. m_nCellGroup[2] = i;
  349. flag3 |= cache.IsAutoV();
  350. }
  351. }
  352. else if (cache.IsAutoU() && !cache.IsStarU())
  353. {
  354. cache.nNext = m_nCellGroup[1];
  355. m_nCellGroup[1] = i;
  356. }
  357. else
  358. {
  359. cache.nNext = m_nCellGroup[3];
  360. m_nCellGroup[3] = i;
  361. }
  362. }
  363. m_bHasStarCellsU = flag;
  364. m_bHasStarCellsV = flag2;
  365. m_bHasGroup2CellsInAutoRows = flag3;
  366. }
  367. int CXTPMarkupGrid::GetMeasureSizeForRange(CXTPMarkupDefinitionCollection* pDefinitions, int start, int count)
  368. {
  369. double num = 0;
  370. for (int nIndex = start; nIndex < start + count; nIndex++)
  371. {
  372. CXTPMarkupDefinitionBase* pDefinition = pDefinitions->GetItem(nIndex);
  373. num += pDefinition->m_nSizeType == sizeTypeAuto ? pDefinition->m_nMinSize : pDefinition->m_nMeasureSize;
  374. }
  375. return (int)num;
  376. }
  377. void CXTPMarkupGrid::MeasureCell(CXTPMarkupDrawingContext* pDC, int cell, BOOL forceInfinityV)
  378. {
  379. int nPositiveInfinity;
  380. int num2;
  381. if (m_pCellCachesCollection[cell].IsAutoU() && !m_pCellCachesCollection[cell].IsStarU())
  382. {
  383. nPositiveInfinity = INT_MAX;
  384. }
  385. else
  386. {
  387. nPositiveInfinity = GetMeasureSizeForRange(m_pDefinitionsU, m_pCellCachesCollection[cell].nColumnIndex, m_pCellCachesCollection[cell].nColumnSpan);
  388. }
  389. if (forceInfinityV)
  390. {
  391. num2 = INT_MAX;
  392. }
  393. else if (m_pCellCachesCollection[cell].IsAutoV() && !m_pCellCachesCollection[cell].IsStarV())
  394. {
  395. num2 = INT_MAX;
  396. }
  397. else
  398. {
  399. num2 = GetMeasureSizeForRange(m_pDefinitionsV, m_pCellCachesCollection[cell].nRowIndex, m_pCellCachesCollection[cell].nRowSpan);
  400. }
  401. CXTPMarkupUIElement* pElement = GetChildren()->GetItem(cell);
  402. if (pElement != NULL)
  403. {
  404. pElement->Measure(pDC, CSize(nPositiveInfinity, num2));
  405. }
  406. }
  407. void CXTPMarkupGrid::MeasureCellsGroup(CXTPMarkupDrawingContext* pDC, int cellsHead, CSize /*referenceSize*/, BOOL ignoreDesiredSizeU, BOOL forceInfinityV)
  408. {
  409. int nCount = GetChildren()->GetCount();
  410. if (cellsHead < nCount)
  411. {
  412. BOOL flag = forceInfinityV;
  413. int cell = cellsHead;
  414. do
  415. {
  416. CELLCACHE& cellCache =  m_pCellCachesCollection[cell];
  417. MeasureCell(pDC, cell, forceInfinityV);
  418. if (!ignoreDesiredSizeU)
  419. {
  420. if (cellCache.nColumnSpan == 1)
  421. {
  422. m_pDefinitionsU->GetItem(cellCache.nColumnIndex)->UpdateMinSize(GetChildren()->GetItem(cell)->GetDesiredSize().cx);
  423. }
  424. else
  425. {
  426. ASSERT(FALSE);
  427. }
  428. }
  429. if (!flag)
  430. {
  431. if (cellCache.nRowSpan == 1)
  432. {
  433. m_pDefinitionsV->GetItem(cellCache.nRowIndex)->UpdateMinSize(GetChildren()->GetItem(cell)->GetDesiredSize().cy);
  434. }
  435. else
  436. {
  437. ASSERT(FALSE);
  438. }
  439. }
  440. cell = cellCache.nNext;
  441. }
  442. while (cell < nCount);
  443. }
  444. }
  445. void CXTPMarkupGrid::ValidateDefinitions()
  446. {
  447. MARKUP_RELEASE(m_pDefinitionsU);
  448. MARKUP_RELEASE(m_pDefinitionsV);
  449. if (m_pColumnDefinitions->GetCount() == 0)
  450. {
  451. m_pDefinitionsU = new CXTPMarkupColumnDefinitionCollection();
  452. m_pDefinitionsU->Add(new CXTPMarkupColumnDefinition());
  453. }
  454. else
  455. {
  456. m_pDefinitionsU = m_pColumnDefinitions;
  457. m_pDefinitionsU->AddRef();
  458. }
  459. if (m_pRowDefinitions->GetCount() == 0)
  460. {
  461. m_pDefinitionsV = new CXTPMarkupRowDefinitionCollection();
  462. m_pDefinitionsV->Add(new CXTPMarkupRowDefinition());
  463. }
  464. else
  465. {
  466. m_pDefinitionsV = m_pRowDefinitions;
  467. m_pDefinitionsV->AddRef();
  468. }
  469. }
  470. int CXTPMarkupGrid::CalculateDesiredSize(CXTPMarkupDefinitionCollection* pDefinitions)
  471. {
  472. int num = 0;
  473. for (int i = 0; i < pDefinitions->GetCount(); i++)
  474. {
  475. num += pDefinitions->GetItem(i)->m_nMinSize;
  476. }
  477. return num;
  478. }
  479. void CXTPMarkupGrid::ResolveStar(CXTPMarkupDefinitionCollection* pDefinitions, double availableSize)
  480. {
  481. CXTPMarkupDefinitionBase** pTempDefinitions = new CXTPMarkupDefinitionBase*[pDefinitions->GetCount()];
  482. int length = 0;
  483. double num2 = 0;
  484. for (int i = 0; i < pDefinitions->GetCount(); i++)
  485. {
  486. CXTPMarkupDefinitionBase* pDefinition = pDefinitions->GetItem(i);
  487. switch (pDefinition->m_nSizeType)
  488. {
  489. case sizeTypePixel:
  490. num2 += pDefinition->m_nMeasureSize;
  491. continue;
  492. case sizeTypeAuto:
  493. num2 +=  pDefinition->m_nMinSize;
  494. continue;
  495. case sizeTypeStar:
  496. {
  497. pTempDefinitions[length++] = pDefinition;
  498. double num4 = pDefinition->GetUserSize()->GetValue();
  499. if (num4 != 0)
  500. {
  501. pDefinition->m_nMeasureSize = num4;
  502. double num5 = IsNan(pDefinition->GetUserMaxSize()) ? pDefinition->m_nMinSize : max(pDefinition->m_nMinSize, pDefinition->GetUserMaxSize());
  503. pDefinition->m_nSizeCache = num5 / num4;
  504. }
  505. else
  506. {
  507. pDefinition->m_nMeasureSize = 0;
  508. pDefinition->m_nSizeCache = 0;
  509. }
  510. continue;
  511. }
  512. }
  513. }
  514. if (length > 0)
  515. {
  516. qsort(pTempDefinitions, length, sizeof(CXTPMarkupDefinitionBase*), StarDistributionOrderComparer);
  517. int nIndex;
  518. double num6 = 0;
  519. for (nIndex = length - 1; nIndex >= 0; nIndex--)
  520. {
  521. num6 += pTempDefinitions[nIndex]->m_nMeasureSize;
  522. pTempDefinitions[nIndex]->m_nSizeCache = num6;
  523. }
  524. for (nIndex = 0; nIndex < length; nIndex++)
  525. {
  526. CXTPMarkupDefinitionBase* pDefinition = pTempDefinitions[nIndex];
  527. int nMinSize;
  528. double nMeasureSize = pDefinition->m_nMeasureSize;
  529. if (nMeasureSize == 0)
  530. {
  531. nMinSize = pDefinition->m_nMinSize;
  532. }
  533. else
  534. {
  535. int num10 = (int)(max((double) (availableSize - num2), (double) 0) * (nMeasureSize / pDefinition->m_nSizeCache));
  536. nMinSize = min(num10, pDefinition->GetUserMaxSize());
  537. nMinSize = max(pDefinition->m_nMinSize, nMinSize);
  538. }
  539. pDefinition->m_nMeasureSize = nMinSize;
  540. num2 += nMinSize;
  541. }
  542. }
  543. delete[] pTempDefinitions;
  544. }
  545. CSize CXTPMarkupGrid::MeasureOverride(CXTPMarkupDrawingContext* pDC, CSize constraint)
  546. {
  547. CSize size(0, 0);
  548. if (m_pColumnDefinitions->GetCount() == 0 && m_pRowDefinitions->GetCount() == 0)
  549. {
  550. int nCount = m_pChildren->GetCount();
  551. for (int i = 0; i < nCount; i++)
  552. {
  553. CXTPMarkupUIElement* pElement = m_pChildren->GetItem(i);
  554. if (pElement == NULL)
  555. continue;
  556. pElement->Measure(pDC, constraint);
  557. size.cx = max(size.cx, pElement->GetDesiredSize().cx);
  558. size.cy = max(size.cy, pElement->GetDesiredSize().cy);
  559. }
  560. return size;
  561. }
  562. BOOL bTreatStarAsAuto = IsPositiveInfinity(constraint.cx);
  563. BOOL bFlag2 = IsPositiveInfinity(constraint.cy);
  564. ValidateDefinitions();
  565. ValidateDefinitionsLayout(m_pDefinitionsU, bTreatStarAsAuto);
  566. ValidateDefinitionsLayout(m_pDefinitionsV, bFlag2);
  567. ValidateCells();
  568. MeasureCellsGroup(pDC, m_nCellGroup[0], constraint, FALSE, FALSE);
  569. if (!m_bHasGroup2CellsInAutoRows)
  570. {
  571. if (m_bHasStarCellsV)
  572. {
  573. ResolveStar(m_pDefinitionsV, constraint.cy);
  574. }
  575. MeasureCellsGroup(pDC, m_nCellGroup[1], constraint, FALSE, FALSE);
  576. if (m_bHasStarCellsU)
  577. {
  578. ResolveStar(m_pDefinitionsU, constraint.cx);
  579. }
  580. MeasureCellsGroup(pDC, m_nCellGroup[2], constraint, FALSE, FALSE);
  581. }
  582. else if (m_nCellGroup[1] > GetChildren()->GetCount())
  583. {
  584. if (m_bHasStarCellsU)
  585. {
  586. ResolveStar(m_pDefinitionsU, constraint.cx);
  587. }
  588. MeasureCellsGroup(pDC, m_nCellGroup[2], constraint, FALSE, FALSE);
  589. if (m_bHasStarCellsV)
  590. {
  591. ResolveStar(m_pDefinitionsV, constraint.cy);
  592. }
  593. }
  594. else
  595. {
  596. MeasureCellsGroup(pDC, m_nCellGroup[1], constraint, FALSE, TRUE);
  597. if (m_bHasStarCellsU)
  598. {
  599. ResolveStar(m_pDefinitionsU, constraint.cx);
  600. }
  601. MeasureCellsGroup(pDC, m_nCellGroup[2], constraint, FALSE, FALSE);
  602. if (m_bHasStarCellsV)
  603. {
  604. ResolveStar(m_pDefinitionsV, constraint.cy);
  605. }
  606. MeasureCellsGroup(pDC, m_nCellGroup[1], constraint, TRUE, FALSE);
  607. }
  608. MeasureCellsGroup(pDC, m_nCellGroup[3], constraint, FALSE, FALSE);
  609. size = CSize(CalculateDesiredSize(m_pDefinitionsU), CalculateDesiredSize(m_pDefinitionsV));
  610. return size;
  611. }
  612. int _cdecl CXTPMarkupGrid::DistributionOrderComparer(const void *arg1, const void *arg2)
  613. {
  614. CXTPMarkupDefinitionBase* base2 = *((CXTPMarkupDefinitionBase**)arg1);
  615. CXTPMarkupDefinitionBase* base3 = *((CXTPMarkupDefinitionBase**)arg2);
  616. if ((base2->m_nSizeCache - base2->m_nMinSize) == (base3->m_nSizeCache - base3->m_nMinSize))
  617. {
  618. return 0;
  619. }
  620. else if ((base2->m_nSizeCache - base2->m_nMinSize) < (base3->m_nSizeCache - base3->m_nMinSize))
  621. {
  622. return -1;
  623. }
  624. return 1;
  625. };
  626. int _cdecl CXTPMarkupGrid::StarDistributionOrderComparer(const void *arg1, const void *arg2)
  627. {
  628. CXTPMarkupDefinitionBase* base2 = *((CXTPMarkupDefinitionBase**)arg1);
  629. CXTPMarkupDefinitionBase* base3 = *((CXTPMarkupDefinitionBase**)arg2);
  630. if (base2->m_nSizeCache == base3->m_nSizeCache)
  631. {
  632. return 0;
  633. }
  634. else if (base2->m_nSizeCache < base3->m_nSizeCache)
  635. {
  636. return -1;
  637. }
  638. return 1;
  639. };
  640. void CXTPMarkupGrid::SetFinalSize(CXTPMarkupDefinitionCollection* pDefinitions, int finalSize)
  641. {
  642. CXTPMarkupDefinitionBase** pTempDefinitions = new CXTPMarkupDefinitionBase*[pDefinitions->GetCount()];
  643. int length = 0;
  644. int num2 = pDefinitions->GetCount();
  645. double num3 = 0;
  646. for (int i = 0; i < pDefinitions->GetCount(); i++)
  647. {
  648. CXTPMarkupDefinitionBase* pDefinition = pDefinitions->GetItem(i);
  649. if (pDefinition->GetUserSize()->IsStar())
  650. {
  651. pTempDefinitions[length++] = pDefinition;
  652. double d = pDefinition->GetUserSize()->GetValue();
  653. if (d == 0)
  654. {
  655. pDefinition->m_nMeasureSize = 0;
  656. pDefinition->m_nSizeCache = 0;
  657. }
  658. else
  659. {
  660. pDefinition->m_nMeasureSize = d;
  661. int num6 = IsNan(pDefinition->GetUserMaxSize()) ? pDefinition->m_nMinSize : max(pDefinition->m_nMinSize, pDefinition->GetUserMaxSize());
  662. pDefinition->m_nSizeCache = (double)num6 / (double)d;
  663. }
  664. }
  665. else
  666. {
  667. pTempDefinitions[--num2] = pDefinition;
  668. double nMinSizeForArrange = 0;
  669. switch (pDefinition->GetUserSize()->GetUnitType())
  670. {
  671. case CXTPMarkupGridLength::unitTypeAuto:
  672. nMinSizeForArrange = pDefinition->m_nMinSize;
  673. break;
  674. case CXTPMarkupGridLength::unitTypePixel:
  675. nMinSizeForArrange = pDefinition->GetUserSize()->GetValue();
  676. break;
  677. }
  678. int nUserMaxSize = pDefinition->GetUserMaxSize();
  679. pDefinition->m_nSizeCache = max(pDefinition->m_nMinSize, min(nMinSizeForArrange, nUserMaxSize));
  680. num3 += pDefinition->m_nSizeCache;
  681. }
  682. }
  683. if (length > 0)
  684. {
  685. qsort(pTempDefinitions, length, sizeof(CXTPMarkupDefinitionBase*), StarDistributionOrderComparer);
  686. double num9 = 0;
  687. int nIndex;
  688. for (nIndex = length - 1; nIndex >= 0; nIndex--)
  689. {
  690. num9 += pTempDefinitions[nIndex]->m_nMeasureSize;
  691. pTempDefinitions[nIndex]->m_nSizeCache = num9;
  692. }
  693. for (nIndex = 0; nIndex < length; nIndex++)
  694. {
  695. CXTPMarkupDefinitionBase* pDefinition = pTempDefinitions[nIndex];
  696. int num11;
  697. double nMeasureSize = pDefinition->m_nMeasureSize;
  698. if (nMeasureSize == 0)
  699. {
  700. num11 = pDefinition->m_nMinSize;
  701. }
  702. else
  703. {
  704. double num13 = max((double) (finalSize - num3), (double) 0) * (nMeasureSize / pDefinition->m_nSizeCache);
  705. num11 = min((int)num13, pDefinition->GetUserMaxSize());
  706. num11 = max(pDefinition->m_nMinSize, num11);
  707. }
  708. pDefinition->m_nSizeCache = num11;
  709. num3 += num11;
  710. }
  711. }
  712. if (num3 > finalSize)
  713. {
  714. qsort(pTempDefinitions, length, sizeof(CXTPMarkupDefinitionBase*), DistributionOrderComparer);
  715. double num14 = finalSize - num3;
  716. for (int k = 0; k < pDefinitions->GetCount(); k++)
  717. {
  718. double num16 = pTempDefinitions[k]->m_nSizeCache + (num14 / ((double) (pDefinitions->GetCount() - k)));
  719. num16 = min(max(num16, pTempDefinitions[k]->m_nMinSize), pTempDefinitions[k]->m_nSizeCache);
  720. num14 -= num16 - pTempDefinitions[k]->m_nSizeCache;
  721. pTempDefinitions[k]->m_nSizeCache = num16;
  722. }
  723. }
  724. pDefinitions->GetItem(0)->m_nFinalOffset = 0;
  725. for (int j = 1; j < pDefinitions->GetCount(); j++)
  726. {
  727. pDefinitions->GetItem(j)->m_nFinalOffset = pDefinitions->GetItem(j - 1)->m_nFinalOffset + (int)pDefinitions->GetItem(j - 1)->m_nSizeCache;
  728. }
  729. delete[] pTempDefinitions;
  730. }
  731. int CXTPMarkupGrid::GetFinalSizeForRange(CXTPMarkupDefinitionCollection* pDefinitions, int start, int count)
  732. {
  733. int num = 0;
  734. for (int nIndex = start; nIndex < start + count; nIndex++)
  735. {
  736. num += (int)pDefinitions->GetItem(nIndex)->m_nSizeCache;
  737. }
  738. return num;
  739. }
  740. CSize CXTPMarkupGrid::ArrangeOverride(CSize arrangeSize)
  741. {
  742. if ((m_pColumnDefinitions->GetCount() == 0 && m_pRowDefinitions->GetCount() == 0) || (m_pCellCachesCollection == NULL))
  743. {
  744. int nCount = m_pChildren->GetCount();
  745. for (int i = 0; i < nCount; i++)
  746. {
  747. CXTPMarkupUIElement* pElement = m_pChildren->GetItem(i);
  748. if (pElement == NULL)
  749. continue;
  750. pElement->Arrange(CRect(0, 0, arrangeSize.cx, arrangeSize.cy));
  751. }
  752. return arrangeSize;
  753. }
  754. SetFinalSize(m_pDefinitionsU, arrangeSize.cx);
  755. SetFinalSize(m_pDefinitionsV, arrangeSize.cy);
  756. int nCount = m_pChildren->GetCount();
  757. for (int i = 0; i < nCount; i++)
  758. {
  759. CXTPMarkupUIElement* pElement = m_pChildren->GetItem(i);
  760. if (pElement == NULL)
  761. continue;
  762. CELLCACHE& cellCache =  m_pCellCachesCollection[i];
  763. int columnIndex = cellCache.nColumnIndex;
  764. int rowIndex = cellCache.nRowIndex;
  765. int columnSpan = cellCache.nColumnSpan;
  766. int rowSpan = cellCache.nRowSpan;
  767. CRect finalRect(CPoint(m_pDefinitionsU->GetItem(columnIndex)->m_nFinalOffset,
  768. m_pDefinitionsV->GetItem(rowIndex)->m_nFinalOffset),
  769. CSize(GetFinalSizeForRange(m_pDefinitionsU, columnIndex, columnSpan),
  770. GetFinalSizeForRange(m_pDefinitionsV, rowIndex, rowSpan)));
  771. pElement->Arrange(finalRect);
  772. }
  773. return arrangeSize;
  774. }