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

对话框与窗口

开发平台:

Visual C++

  1. // XTPMarkupFrameworkElement.cpp: implementation of the CXTPMarkupFrameworkElement 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 "XTPMarkupFrameworkElement.h"
  22. #include "XTPMarkupBuilder.h"
  23. #include "XTPMarkupResourceDictionary.h"
  24. #ifdef _DEBUG
  25. #undef THIS_FILE
  26. static char THIS_FILE[]=__FILE__;
  27. #define new DEBUG_NEW
  28. #endif
  29. //////////////////////////////////////////////////////////////////////////
  30. // CXTPMarkupFrameworkElement
  31. CXTPMarkupDependencyProperty* CXTPMarkupFrameworkElement::m_pMarginProperty = NULL;
  32. CXTPMarkupDependencyProperty* CXTPMarkupFrameworkElement::m_pHorizontalAlignmentProperty = NULL;
  33. CXTPMarkupDependencyProperty* CXTPMarkupFrameworkElement::m_pVerticalAlignmentProperty = NULL;
  34. CXTPMarkupDependencyProperty* CXTPMarkupFrameworkElement::m_pWidthProperty = NULL;
  35. CXTPMarkupDependencyProperty* CXTPMarkupFrameworkElement::m_pHeightProperty = NULL;
  36. CXTPMarkupDependencyProperty* CXTPMarkupFrameworkElement::m_pMinWidthProperty = NULL;
  37. CXTPMarkupDependencyProperty* CXTPMarkupFrameworkElement::m_pMinHeightProperty = NULL;
  38. CXTPMarkupDependencyProperty* CXTPMarkupFrameworkElement::m_pMaxWidthProperty = NULL;
  39. CXTPMarkupDependencyProperty* CXTPMarkupFrameworkElement::m_pMaxHeightProperty = NULL;
  40. CXTPMarkupDependencyProperty* CXTPMarkupFrameworkElement::m_pTagProperty = NULL;
  41. //////////////////////////////////////////////////////////////////////
  42. // Construction/Destruction
  43. //////////////////////////////////////////////////////////////////////
  44. IMPLEMENT_MARKUPCLASS(L"FrameworkElement", CXTPMarkupFrameworkElement, CXTPMarkupUIElement)
  45. void CXTPMarkupFrameworkElement::RegisterMarkupClass()
  46. {
  47. CXTPMarkupStyle::RegisterType();
  48. m_pMarginProperty = CXTPMarkupDependencyProperty::Register(L"Margin", MARKUP_TYPE(CXTPMarkupThickness), MARKUP_TYPE(CXTPMarkupFrameworkElement),
  49. new CXTPMarkupPropertyMetadata(CXTPMarkupThickness::CreateValue(), CXTPMarkupPropertyMetadata::flagAffectsMeasure));
  50. m_pHorizontalAlignmentProperty = CXTPMarkupDependencyProperty::Register(L"HorizontalAlignment", MARKUP_TYPE(CXTPMarkupEnum), MARKUP_TYPE(CXTPMarkupFrameworkElement),
  51. new CXTPMarkupPropertyMetadata(NULL, &CXTPMarkupBuilder::ConvertHorizontalAlignment, CXTPMarkupPropertyMetadata::flagAffectsArrange));
  52. m_pVerticalAlignmentProperty = CXTPMarkupDependencyProperty::Register(L"VerticalAlignment", MARKUP_TYPE(CXTPMarkupEnum), MARKUP_TYPE(CXTPMarkupFrameworkElement),
  53. new CXTPMarkupPropertyMetadata(NULL, &CXTPMarkupBuilder::ConvertVerticalAlignment, CXTPMarkupPropertyMetadata::flagAffectsArrange));
  54. m_pWidthProperty = CXTPMarkupDependencyProperty::Register(L"Width", MARKUP_TYPE(CXTPMarkupInt), MARKUP_TYPE(CXTPMarkupFrameworkElement),
  55. new CXTPMarkupPropertyMetadata(NULL, CXTPMarkupPropertyMetadata::flagAffectsMeasure));
  56. m_pHeightProperty = CXTPMarkupDependencyProperty::Register(L"Height", MARKUP_TYPE(CXTPMarkupInt), MARKUP_TYPE(CXTPMarkupFrameworkElement),
  57. new CXTPMarkupPropertyMetadata(NULL, CXTPMarkupPropertyMetadata::flagAffectsMeasure));
  58. m_pMinWidthProperty = CXTPMarkupDependencyProperty::Register(L"MinWidth", MARKUP_TYPE(CXTPMarkupInt), MARKUP_TYPE(CXTPMarkupFrameworkElement),
  59. new CXTPMarkupPropertyMetadata(NULL, CXTPMarkupPropertyMetadata::flagAffectsMeasure));
  60. m_pMinHeightProperty = CXTPMarkupDependencyProperty::Register(L"MinHeight", MARKUP_TYPE(CXTPMarkupInt), MARKUP_TYPE(CXTPMarkupFrameworkElement),
  61. new CXTPMarkupPropertyMetadata(NULL, CXTPMarkupPropertyMetadata::flagAffectsMeasure));
  62. m_pMaxWidthProperty = CXTPMarkupDependencyProperty::Register(L"MaxWidth", MARKUP_TYPE(CXTPMarkupInt), MARKUP_TYPE(CXTPMarkupFrameworkElement),
  63. new CXTPMarkupPropertyMetadata(NULL, CXTPMarkupPropertyMetadata::flagAffectsMeasure));
  64. m_pMaxHeightProperty = CXTPMarkupDependencyProperty::Register(L"MaxHeight", MARKUP_TYPE(CXTPMarkupInt), MARKUP_TYPE(CXTPMarkupFrameworkElement),
  65. new CXTPMarkupPropertyMetadata(NULL, CXTPMarkupPropertyMetadata::flagAffectsMeasure));
  66. m_pTagProperty = CXTPMarkupDependencyProperty::Register(L"Tag", MARKUP_TYPE(CXTPMarkupObject), MARKUP_TYPE(CXTPMarkupFrameworkElement));
  67. }
  68. CXTPMarkupFrameworkElement::CXTPMarkupFrameworkElement()
  69. {
  70. m_bNeedsClipBounds = FALSE;
  71. m_bUnclippedDesiredSize = FALSE;
  72. m_szUnclippedDesiredSize = CSize(0, 0);
  73. }
  74. CXTPMarkupFrameworkElement::~CXTPMarkupFrameworkElement()
  75. {
  76. }
  77. CXTPMarkupFrameworkElement::MINMAX::MINMAX()
  78. {
  79. nMaxHeight = nMaxWidth = INT_MAX;
  80. nMinWidth = nMinHeight = 0;
  81. }
  82. AFX_INLINE int InlineMin(int a, int b) {
  83. return a < b ? (a) : (b);
  84. }
  85. AFX_INLINE int InlineMax(int a, int b) {
  86. return a > b ? (a) : (b);
  87. }
  88. void CXTPMarkupFrameworkElement::MINMAX::Update(const CXTPMarkupFrameworkElement* pElement)
  89. {
  90. CXTPMarkupInt* pHeight = MARKUP_STATICCAST(CXTPMarkupInt, pElement->GetValue(CXTPMarkupFrameworkElement::m_pHeightProperty));
  91. CXTPMarkupInt* pMinHeight = MARKUP_STATICCAST(CXTPMarkupInt, pElement->GetValue(CXTPMarkupFrameworkElement::m_pMinHeightProperty));
  92. CXTPMarkupInt* pMaxHeight = MARKUP_STATICCAST(CXTPMarkupInt, pElement->GetValue(CXTPMarkupFrameworkElement::m_pMaxHeightProperty));
  93. CXTPMarkupInt* pWidth = MARKUP_STATICCAST(CXTPMarkupInt, pElement->GetValue(CXTPMarkupFrameworkElement::m_pWidthProperty));
  94. CXTPMarkupInt* pMinWidth = MARKUP_STATICCAST(CXTPMarkupInt, pElement->GetValue(CXTPMarkupFrameworkElement::m_pMinWidthProperty));
  95. CXTPMarkupInt* pMaxWidth = MARKUP_STATICCAST(CXTPMarkupInt, pElement->GetValue(CXTPMarkupFrameworkElement::m_pMaxWidthProperty));
  96. nMaxHeight = InlineMax(InlineMin(pHeight ? (int)*pHeight : INT_MAX, pMaxHeight ? (int)*pMaxHeight : INT_MAX), pMinHeight ? (int)*pMinHeight : 0);
  97. nMinHeight = InlineMax(InlineMin(nMaxHeight, pHeight ? (int)*pHeight : 0), pMinHeight ? (int)*pMinHeight : 0);
  98. nMaxWidth = InlineMax(InlineMin(pWidth ? (int)*pWidth : INT_MAX, pMaxWidth ? (int)*pMaxWidth : INT_MAX), pMinWidth ? (int)*pMinWidth : 0);
  99. nMinWidth = InlineMax(InlineMin(nMaxWidth, pWidth ? (int)*pWidth : 0), pMinWidth ? (int)*pMinWidth : 0);
  100. }
  101. inline int SafeSum(int a, int b)
  102. {
  103. if (a > INT_MAX / 2 || b > INT_MAX / 2)
  104. return INT_MAX;
  105. return a + b;
  106. }
  107. CSize CXTPMarkupFrameworkElement::MeasureCore(CXTPMarkupDrawingContext* pDC, CSize szAvailableSize)
  108. {
  109. CXTPMarkupThickness* pMargin = GetMargin();
  110. long num = pMargin->left + pMargin->right;
  111. long num2 = pMargin->top + pMargin->bottom;
  112. CSize transformSpaceBounds = CSize(max(SafeSum(szAvailableSize.cx, -num), 0), max(SafeSum(szAvailableSize.cy, -num2), 0));
  113. m_mmBounds.Update(this);
  114. transformSpaceBounds.cx = max(m_mmBounds.nMinWidth, min(transformSpaceBounds.cx, m_mmBounds.nMaxWidth));
  115. transformSpaceBounds.cy = max(m_mmBounds.nMinHeight, min(transformSpaceBounds.cy, m_mmBounds.nMaxHeight));
  116. CSize size2 = MeasureOverride(pDC, transformSpaceBounds);
  117. size2 = CSize(max(size2.cx, m_mmBounds.nMinWidth), max(size2.cy, m_mmBounds.nMinHeight));
  118. CSize size = size2;
  119. BOOL fClip = FALSE;
  120. if (size2.cx > m_mmBounds.nMaxWidth)
  121. {
  122. size2.cx = m_mmBounds.nMaxWidth;
  123. fClip = TRUE;
  124. }
  125. if (size2.cy > m_mmBounds.nMaxHeight)
  126. {
  127. size2.cy = m_mmBounds.nMaxHeight;
  128. fClip = TRUE;
  129. }
  130. long width = size2.cx + num;
  131. long height = size2.cy + num2;
  132. if (width > szAvailableSize.cx)
  133. {
  134. width = szAvailableSize.cx;
  135. fClip = TRUE;
  136. }
  137. if (height > szAvailableSize.cy)
  138. {
  139. height = szAvailableSize.cy;
  140. fClip = TRUE;
  141. }
  142. m_bNeedsClipBounds = FALSE;
  143. m_bUnclippedDesiredSize = FALSE;
  144. if ((fClip || (width < 0)) || (height < 0))
  145. {
  146. m_bNeedsClipBounds = TRUE;
  147. m_bUnclippedDesiredSize = TRUE;
  148. m_szUnclippedDesiredSize = size;
  149. }
  150. return CSize(max(0, width), max(0, height));
  151. }
  152. BOOL CXTPMarkupFrameworkElement::GetClipToBounds() const
  153. {
  154. CXTPMarkupBool* pClipToBounds = MARKUP_STATICCAST(CXTPMarkupBool, GetValue(m_pClipToBoundsProperty));
  155. return pClipToBounds && (BOOL)*pClipToBounds;
  156. }
  157. BOOL CXTPMarkupFrameworkElement::GetLayoutClip(CRect& rc) const
  158. {
  159. if (CXTPMarkupUIElement::GetLayoutClip(rc))
  160. return TRUE;
  161. BOOL bClipToBounds = GetClipToBounds();
  162. if (!bClipToBounds && !m_bNeedsClipBounds)
  163. return FALSE;
  164. CSize szRenderSize = m_szRenderSize;
  165. int num = m_mmBounds.nMaxWidth == INT_MAX ? szRenderSize.cx : m_mmBounds.nMaxWidth;
  166. int num2 = m_mmBounds.nMaxHeight == INT_MAX ? szRenderSize.cy : m_mmBounds.nMaxHeight;
  167. BOOL bFlag = bClipToBounds ||num < szRenderSize.cx || num2 < szRenderSize.cy;
  168. szRenderSize = CSize(min(szRenderSize.cx, m_mmBounds.nMaxWidth), min(szRenderSize.cy, m_mmBounds.nMaxHeight));
  169. CXTPMarkupThickness* pMargin = GetMargin();
  170. long num3 = pMargin->left + pMargin->right;
  171. long num4 = pMargin->top + pMargin->bottom;
  172. CSize szClientSize  = CSize(max(m_rcFinalRect.Width() - num3, 0), max(m_rcFinalRect.Height() - num4, 0));
  173. BOOL bFlag2 = bClipToBounds || szClientSize.cx < szRenderSize.cx || szClientSize.cy < szRenderSize.cy;
  174. if (bFlag && !bFlag2)
  175. {
  176. rc = CRect(0, 0, num, num2);
  177. return TRUE;
  178. }
  179. if (!bFlag && !bFlag2)
  180. return FALSE;
  181. CPoint offset = ComputeAlignmentOffset(szClientSize, szRenderSize);
  182. rc = CRect(-offset, szClientSize);
  183. if (bFlag)
  184. {
  185. rc.IntersectRect(rc, CRect(0, 0, num, num2));
  186. }
  187. return TRUE;
  188. }
  189. CSize CXTPMarkupFrameworkElement::MeasureOverride(CXTPMarkupDrawingContext* /*pDC*/, CSize /*szAvailableSize*/)
  190. {
  191. return CSize(0, 0);
  192. }
  193. XTPMarkupHorizontalAlignment CXTPMarkupFrameworkElement::GetHorizontalAlignment() const
  194. {
  195. CXTPMarkupEnum* pAlign = MARKUP_STATICCAST(CXTPMarkupEnum, GetValue(m_pHorizontalAlignmentProperty));
  196. return pAlign ? (XTPMarkupHorizontalAlignment)(int)(*pAlign) : xtpMarkupHorizontalAlignmentStretch;
  197. }
  198. XTPMarkupVerticalAlignment CXTPMarkupFrameworkElement::GetVerticalAlignment() const
  199. {
  200. CXTPMarkupEnum* pAlign = MARKUP_STATICCAST(CXTPMarkupEnum, GetValue(m_pVerticalAlignmentProperty));
  201. return pAlign ? (XTPMarkupVerticalAlignment)(int)(*pAlign) : xtpMarkupVerticalAlignmentStretch;
  202. }
  203. void CXTPMarkupFrameworkElement::ArrangeCore(CRect rcFinalRect)
  204. {
  205. CSize size = rcFinalRect.Size();
  206. CXTPMarkupThickness* pMargin = GetMargin();
  207. long num = pMargin->left +pMargin->right;
  208. long num2 = pMargin->top + pMargin->bottom;
  209. size.cx = max(0, (size.cx - num));
  210. size.cy = max(0, (size.cy - num2));
  211. CSize untransformedDS(0, 0);
  212. if (!m_bUnclippedDesiredSize)
  213. {
  214. untransformedDS = CSize(m_szDesiredSize.cx - num, m_szDesiredSize.cy - num2);
  215. }
  216. else
  217. {
  218. untransformedDS = m_szUnclippedDesiredSize;
  219. }
  220. if (size.cx < untransformedDS.cx)
  221. {
  222. m_bNeedsClipBounds = TRUE;
  223. size.cx = untransformedDS.cx;
  224. }
  225. if (size.cy < untransformedDS.cy)
  226. {
  227. m_bNeedsClipBounds = TRUE;
  228. size.cy = untransformedDS.cy;
  229. }
  230. if (GetHorizontalAlignment() != xtpMarkupHorizontalAlignmentStretch)
  231. {
  232. size.cx = untransformedDS.cx;
  233. }
  234. if (GetVerticalAlignment() != xtpMarkupVerticalAlignmentStretch)
  235. {
  236. size.cy = untransformedDS.cy;
  237. }
  238. long num3 = max(untransformedDS.cx, m_mmBounds.nMaxWidth);
  239. if (num3 < size.cx)
  240. {
  241. m_bNeedsClipBounds = TRUE;
  242. size.cx = num3;
  243. }
  244. long num4 = max(untransformedDS.cy, m_mmBounds.nMaxHeight);
  245. if (num4 < size.cy)
  246. {
  247. m_bNeedsClipBounds = TRUE;
  248. size.cy = num4;
  249. }
  250. CSize size7 = ArrangeOverride(size);
  251. m_szRenderSize = size7;
  252. CSize inkSize = CSize(min(size7.cx, m_mmBounds.nMaxWidth), min(size7.cy, m_mmBounds.nMaxHeight));
  253. if (inkSize.cx < size7.cx || inkSize.cy < size7.cy)
  254. {
  255. m_bNeedsClipBounds = TRUE;
  256. }
  257. CSize clientSize = CSize(max(0, rcFinalRect.Width() - num), max(0, rcFinalRect.Height() - num2));
  258. if (clientSize.cx < inkSize.cx || clientSize.cy < inkSize.cy)
  259. {
  260. m_bNeedsClipBounds = TRUE;
  261. }
  262. CPoint offset = ComputeAlignmentOffset(clientSize, inkSize);
  263. offset.x += rcFinalRect.left + pMargin->left;
  264. offset.y += rcFinalRect.top + pMargin->top;
  265. m_ptVisualOffset = offset;
  266. }
  267. CPoint CXTPMarkupFrameworkElement::ComputeAlignmentOffset(CSize clientSize, CSize inkSize) const
  268. {
  269. CPoint vector(0, 0);
  270. XTPMarkupHorizontalAlignment horizontalAlignment = GetHorizontalAlignment();
  271. XTPMarkupVerticalAlignment verticalAlignment = GetVerticalAlignment();
  272. if ((horizontalAlignment == xtpMarkupHorizontalAlignmentStretch) && (inkSize.cx > clientSize.cx))
  273. {
  274. horizontalAlignment = xtpMarkupHorizontalAlignmentLeft;
  275. }
  276. if ((verticalAlignment == xtpMarkupVerticalAlignmentStretch) && (inkSize.cy > clientSize.cy))
  277. {
  278. verticalAlignment = xtpMarkupVerticalAlignmentTop;
  279. }
  280. switch (horizontalAlignment)
  281. {
  282. case xtpMarkupHorizontalAlignmentCenter:
  283. case xtpMarkupHorizontalAlignmentStretch:
  284. vector.x = (clientSize.cx - inkSize.cx) / 2;
  285. break;
  286. default:
  287. if (horizontalAlignment == xtpMarkupHorizontalAlignmentRight)
  288. {
  289. vector.x = clientSize.cx - inkSize.cx;
  290. }
  291. else
  292. {
  293. vector.x = 0;
  294. }
  295. break;
  296. }
  297. switch (verticalAlignment)
  298. {
  299. case xtpMarkupVerticalAlignmentCenter:
  300. case xtpMarkupVerticalAlignmentStretch:
  301. vector.y = (clientSize.cy - inkSize.cy) / 2;
  302. return vector;
  303. case xtpMarkupVerticalAlignmentBottom:
  304. vector.y = clientSize.cy - inkSize.cy;
  305. return vector;
  306. }
  307. vector.y = 0;
  308. return vector;
  309. }
  310. CSize CXTPMarkupFrameworkElement::ArrangeOverride(CSize szFinalSize)
  311. {
  312. return szFinalSize;
  313. }
  314. void CXTPMarkupFrameworkElement::OnPropertyChanged(CXTPMarkupDependencyProperty* pProperty, CXTPMarkupObject* pOldValue, CXTPMarkupObject* pNewValue)
  315. {
  316. CXTPMarkupUIElement::OnPropertyChanged(pProperty, pOldValue, pNewValue);
  317. FireTriggers(pProperty, pNewValue);
  318. if (pProperty->GetFlags() & CXTPMarkupPropertyMetadata::flagAffectsMeasure)
  319. {
  320. InvalidateMeasure();
  321. }
  322. if (pProperty->GetFlags() & CXTPMarkupPropertyMetadata::flagAffectsArrange)
  323. {
  324. InvalidateArrange();
  325. }
  326. if (pProperty->GetFlags() & CXTPMarkupPropertyMetadata::flagAffectsRender)
  327. {
  328. InvalidateVisual();
  329. }
  330. }