You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

399 lines
9.3 KiB
C++

// XTPMarkupUIElement.cpp: implementation of the CXTPMarkupUIElement class.
//
// This file is a part of the XTREME TOOLKIT PRO MFC class library.
// (c)1998-2012 Codejock Software, All Rights Reserved.
//
// THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
// RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
// CONSENT OF CODEJOCK SOFTWARE.
//
// THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
// IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
// YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
// SINGLE COMPUTER.
//
// CONTACT INFORMATION:
// support@codejock.com
// http://www.codejock.com
//
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "XTPMarkupObject.h"
#include "XTPMarkupInputElement.h"
#include "XTPMarkupUIElement.h"
#include "XTPMarkupDrawingContext.h"
#include "XTPMarkupContext.h"
#include "XTPMarkupBuilder.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
IMPLEMENT_MARKUPCLASS(NULL, CXTPMarkupVisual, CXTPMarkupInputElement);
void CXTPMarkupVisual::RegisterMarkupClass()
{
}
CXTPMarkupVisual::CXTPMarkupVisual()
{
m_ptVisualOffset = CPoint(0, 0);
m_szRenderSize = 0;
m_rcBoundRect.SetRectEmpty();
}
BOOL CXTPMarkupVisual::GetLayoutClip(CRect& /*rc*/) const
{
return FALSE;
}
void CXTPMarkupVisual::RenderClipped(CXTPMarkupDrawingContext* drawingContext)
{
int nVisualCount = GetVisualChildrenCount();
for (int i = 0; i < nVisualCount; i++)
{
GetVisualChild(i)->RenderClipped(drawingContext);
}
}
void CXTPMarkupVisual::Render(CXTPMarkupDrawingContext* drawingContext)
{
CRect rcClipBox = drawingContext->GetClipBox();
rcClipBox.OffsetRect(-m_ptVisualOffset);
RECT rcIntersect;
if (!::IntersectRect(&rcIntersect, GetBoundRect(), &rcClipBox))
{
RenderClipped(drawingContext);
return;
}
CRect rcLayoutClip(0, 0, 0, 0);
BOOL bClipLayout = FALSE;
if (GetLayoutClip(rcLayoutClip))
{
if (rcLayoutClip.IsRectEmpty())
{
RenderClipped(drawingContext);
return;
}
rcClipBox.IntersectRect(rcClipBox, rcLayoutClip);
if (!::IntersectRect(&rcIntersect, GetBoundRect(), &rcClipBox))
{
RenderClipped(drawingContext);
return;
}
bClipLayout = TRUE;
}
drawingContext->OffsetViewport(m_ptVisualOffset);
HRGN hrgnClip = 0;
if (bClipLayout)
{
hrgnClip = drawingContext->SaveClipRegion();
drawingContext->IntersectClipRect(rcLayoutClip);
}
OnRender(drawingContext);
int nVisualCount = GetVisualChildrenCount();
for (int i = 0; i < nVisualCount; i++)
{
GetVisualChild(i)->Render(drawingContext);
}
if (IsKeyboardFocused())
{
OnRenderFocusVisual(drawingContext);
}
if (hrgnClip != NULL)
{
drawingContext->RestoreClipRegion(hrgnClip);
}
drawingContext->OffsetViewport(-m_ptVisualOffset);
}
int CXTPMarkupVisual::GetVisualChildrenCount() const
{
return 0;
}
CXTPMarkupVisual* CXTPMarkupVisual::GetVisualChild(int /*nIndex*/) const
{
ASSERT(FALSE);
return NULL;
}
int CXTPMarkupVisual::GetLogicalChildrenCount() const
{
return GetVisualChildrenCount();
}
CXTPMarkupObject* CXTPMarkupVisual::GetLogicalChild(int nIndex) const
{
return GetVisualChild(nIndex);
}
CXTPMarkupInputElement* CXTPMarkupVisual::InputHitTest(CPoint point) const
{
CPoint ptVisualPoint = point - m_ptVisualOffset;
if (!m_rcBoundRect.PtInRect(ptVisualPoint))
return NULL;
CRect rcClip;
if (GetLayoutClip(rcClip))
{
if (!rcClip.PtInRect(ptVisualPoint))
return NULL;
}
int nVisualCount = GetVisualChildrenCount();
for (int i = nVisualCount - 1; i >= 0; i--)
{
CXTPMarkupInputElement* pObject = GetVisualChild(i)->InputHitTest(ptVisualPoint);
if (pObject)
return pObject;
}
CRect rcRender(0, 0, m_szRenderSize.cx, m_szRenderSize.cy);
if (!rcRender.PtInRect(ptVisualPoint))
return NULL;
return InputHitTestOverride(ptVisualPoint);
}
void CXTPMarkupVisual::UpdateBoundRect()
{
m_rcBoundRect.SetRect(0, 0, m_szRenderSize.cx, m_szRenderSize.cy);
int nVisualCount = GetVisualChildrenCount();
for (int i = 0; i < nVisualCount; i++)
{
CXTPMarkupVisual* pVisual = GetVisualChild(i);
pVisual->UpdateBoundRect();
CRect rcBoundRect = pVisual->m_rcBoundRect;
rcBoundRect.OffsetRect(pVisual->m_ptVisualOffset);
m_rcBoundRect.UnionRect(m_rcBoundRect, rcBoundRect);
}
}
CXTPMarkupInputElement* CXTPMarkupVisual::InputHitTestOverride(CPoint /*point*/) const
{
return (CXTPMarkupInputElement*)this;
}
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CXTPMarkupDependencyProperty* CXTPMarkupUIElement::m_pClipToBoundsProperty = NULL;
CXTPMarkupDependencyProperty* CXTPMarkupUIElement::m_pVisibilityProperty = NULL;
CXTPMarkupDependencyProperty* CXTPMarkupUIElement::m_pFocusableProperty = NULL;
CXTPMarkupDependencyProperty* CXTPMarkupUIElement::m_pIsEnabledProperty = NULL;
IMPLEMENT_MARKUPCLASS(NULL, CXTPMarkupUIElement, CXTPMarkupVisual);
void CXTPMarkupUIElement::RegisterMarkupClass()
{
m_pClipToBoundsProperty = CXTPMarkupDependencyProperty::Register(L"ClipToBounds", MARKUP_TYPE(CXTPMarkupBool), MARKUP_TYPE(CXTPMarkupUIElement));
m_pVisibilityProperty = CXTPMarkupDependencyProperty::Register(L"Visibility", MARKUP_TYPE(CXTPMarkupEnum), MARKUP_TYPE(CXTPMarkupUIElement),
new CXTPMarkupPropertyMetadata(NULL, &CXTPMarkupBuilder::ConvertVisibility, CXTPMarkupPropertyMetadata::flagAffectsMeasure));
m_pFocusableProperty = CXTPMarkupDependencyProperty::Register(L"Focusable", MARKUP_TYPE(CXTPMarkupBool), MARKUP_TYPE(CXTPMarkupUIElement),
new CXTPMarkupPropertyMetadata(CXTPMarkupBool::CreateFalseValue()));
m_pIsEnabledProperty = CXTPMarkupDependencyProperty::Register(L"IsEnabled", MARKUP_TYPE(CXTPMarkupBool), MARKUP_TYPE(CXTPMarkupUIElement),
new CXTPMarkupPropertyMetadata(CXTPMarkupBool::CreateTrueValue()));
}
CXTPMarkupUIElement::CXTPMarkupUIElement()
{
m_szDesiredSize = 0;
m_rcFinalRect.SetRectEmpty();
m_bNeverMeasured = TRUE;
m_bMeasureDirty = FALSE;
m_bNeverArranged = TRUE;
m_bArrangeDirty = FALSE;
m_szPreviousAvailableSize = 0;
m_bArrangeInProgress = FALSE;
m_bMeasureInProgress = FALSE;
}
CXTPMarkupUIElement::~CXTPMarkupUIElement()
{
}
CXTPMarkupVisual* CXTPMarkupVisual::GetVisualParent() const
{
CXTPMarkupObject* pUIElement = m_pLogicalParent;
while (pUIElement && !pUIElement->IsKindOf(MARKUP_TYPE(CXTPMarkupVisual)))
{
pUIElement = pUIElement->GetLogicalParent();
}
return (CXTPMarkupVisual*)pUIElement;
}
void CXTPMarkupUIElement::InvalidateArrange()
{
if (!m_bArrangeInProgress && !m_bNeverArranged)
{
m_bArrangeDirty = TRUE;
Arrange(m_rcFinalRect);
InvalidateVisual();
}
}
void CXTPMarkupUIElement::InvalidateMeasure()
{
CXTPMarkupDrawingContext dc(GetMarkupContext());
InvalidateMeasureOverride(&dc);
}
void CXTPMarkupUIElement::InvalidateMeasureOverride(CXTPMarkupDrawingContext* pDC)
{
if (!m_bMeasureInProgress && !m_bNeverMeasured)
{
m_bMeasureDirty = TRUE;
m_bArrangeDirty = TRUE;
CSize sz = GetDesiredSize();
Measure(pDC, m_szPreviousAvailableSize);
if (sz != GetDesiredSize())
{
m_bMeasureDirty = TRUE;
m_bArrangeDirty = TRUE;
CXTPMarkupUIElement* pParent = MARKUP_DYNAMICCAST(CXTPMarkupUIElement, GetVisualParent());
if (pParent)
{
pParent->InvalidateMeasureOverride(pDC);
}
else if (m_pMarkupContext)
{
m_pMarkupContext->OnInvalidateArrange(this);
}
}
else
{
Arrange(m_rcFinalRect);
InvalidateVisual();
}
}
}
void CXTPMarkupUIElement::InvalidateVisual()
{
if (m_pMarkupContext) m_pMarkupContext->OnInvalidateVisual(this);
}
void CXTPMarkupUIElement::Arrange(CRect rcFinalRect)
{
if (GetVisibility() == xtpMarkupVisibilityCollapsed)
{
m_rcFinalRect = rcFinalRect;
m_bArrangeDirty = FALSE;
m_bNeverArranged = FALSE;
return;
}
if (m_bNeverMeasured)
{
CXTPMarkupDrawingContext dc(GetMarkupContext());
Measure(&dc, rcFinalRect.Size());
}
if ((m_bArrangeDirty || m_bNeverArranged) || (rcFinalRect != m_rcFinalRect))
{
m_bNeverArranged = FALSE;
m_bArrangeInProgress = TRUE;
ArrangeCore(rcFinalRect);
m_bArrangeInProgress = FALSE;
UpdateBoundRect();
}
m_rcFinalRect = rcFinalRect;
m_bArrangeDirty = FALSE;
}
void CXTPMarkupUIElement::ArrangeCore(CRect rcFinalRect)
{
m_szRenderSize = rcFinalRect.Size();
}
void CXTPMarkupUIElement::Measure(CXTPMarkupDrawingContext* pDC, CSize szAvailableSize)
{
if (GetVisibility() == xtpMarkupVisibilityCollapsed)
{
m_bMeasureDirty = TRUE;
m_bNeverMeasured = FALSE;
m_szPreviousAvailableSize = szAvailableSize;
m_szDesiredSize = CSize(0, 0);
return;
}
if ((!m_bMeasureDirty && !m_bNeverMeasured) && (szAvailableSize == m_szPreviousAvailableSize) && !pDC->IsPrinting())
{
return;
}
m_bNeverMeasured = FALSE;
m_bArrangeDirty = TRUE;
m_bMeasureInProgress = TRUE;
CSize size = MeasureCore(pDC, szAvailableSize);
m_bMeasureInProgress = FALSE;
m_szDesiredSize = size;
m_szPreviousAvailableSize = szAvailableSize;
m_bMeasureDirty = pDC->IsPrinting() ? TRUE : FALSE;
}
CSize CXTPMarkupUIElement::MeasureCore(CXTPMarkupDrawingContext* /*pDC*/, CSize /*szAvailableSize*/)
{
return CSize(0, 0);
}
BOOL CXTPMarkupUIElement::GetLayoutClip(CRect& rc) const
{
if (GetVisibility() != xtpMarkupVisibilityVisible)
{
rc.SetRectEmpty();
return TRUE;
}
return FALSE;
}