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.
441 lines
12 KiB
C++
441 lines
12 KiB
C++
// XTPMarkupResourceDictionary.cpp: implementation of the CXTPMarkupResourceDictionary 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 "XTPMarkupFrameworkElement.h"
|
|
|
|
#include "XTPMarkupResourceDictionary.h"
|
|
#include "XTPMarkupBuilder.h"
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[]=__FILE__;
|
|
#define new DEBUG_NEW
|
|
#endif
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// CXTPMarkupResourceDictionary
|
|
|
|
IMPLEMENT_MARKUPCLASS(NULL, CXTPMarkupResourceDictionary, CXTPMarkupObject)
|
|
|
|
void CXTPMarkupResourceDictionary::RegisterMarkupClass()
|
|
{
|
|
|
|
}
|
|
|
|
CXTPMarkupResourceDictionary::CXTPMarkupResourceDictionary()
|
|
{
|
|
|
|
}
|
|
|
|
CXTPMarkupResourceDictionary::~CXTPMarkupResourceDictionary()
|
|
{
|
|
CXTPMarkupObject* pKey;
|
|
CXTPMarkupObject* pValue;
|
|
|
|
POSITION pos = m_mapDictionary.GetStartPosition();
|
|
while (pos)
|
|
{
|
|
m_mapDictionary.GetNextAssoc(pos, pKey, pValue);
|
|
|
|
MARKUP_RELEASE(pKey);
|
|
MARKUP_RELEASE(pValue);
|
|
}
|
|
}
|
|
|
|
CXTPMarkupObject* CXTPMarkupResourceDictionary::Lookup(const CXTPMarkupObject* pKey) const
|
|
{
|
|
CXTPMarkupObject* pValue;
|
|
|
|
if (m_mapDictionary.Lookup((CXTPMarkupObject*)pKey, pValue))
|
|
return pValue;
|
|
|
|
return NULL;
|
|
}
|
|
|
|
void CXTPMarkupResourceDictionary::Add(CXTPMarkupObject* pKey, CXTPMarkupObject* pValue)
|
|
{
|
|
m_mapDictionary.SetAt(pKey, pValue);
|
|
}
|
|
|
|
CXTPMarkupObject* CXTPMarkupResourceDictionary::GetObjectKey(CXTPMarkupObject* pContent) const
|
|
{
|
|
if (!pContent)
|
|
return NULL;
|
|
|
|
CXTPMarkupObject* pKey = pContent->GetValue(m_pKeyProperty);
|
|
if (pKey)
|
|
return pKey;
|
|
|
|
if (MARKUP_DYNAMICCAST(CXTPMarkupStyle, pContent))
|
|
{
|
|
return pContent->GetValue(CXTPMarkupStyle::m_pTargetTypeProperty);
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
void CXTPMarkupResourceDictionary::SetContentObject(CXTPMarkupBuilder* pBuilder, CXTPMarkupObject* pContent)
|
|
{
|
|
CXTPMarkupObject* pKey = GetObjectKey(pContent);
|
|
|
|
if (pKey == NULL)
|
|
{
|
|
pBuilder->ThrowBuilderException(_T("Objects added to Dictionary must have Key attribute or some other type of associated Key"));
|
|
}
|
|
|
|
if (Lookup(pKey))
|
|
{
|
|
pBuilder->ThrowBuilderException(_T("Dictionary key is already used. Key attributes must be unique."));
|
|
}
|
|
|
|
MARKUP_ADDREF(pKey);
|
|
Add(pKey, pContent);
|
|
}
|
|
|
|
CXTPMarkupObject* CXTPMarkupResourceDictionary::FindResource(const CXTPMarkupObject* pElement, const CXTPMarkupObject* pKey)
|
|
{
|
|
if (pElement->IsKindOf(MARKUP_TYPE(CXTPMarkupResourceDictionary)))
|
|
{
|
|
return ((CXTPMarkupResourceDictionary*)pElement)->Lookup(pKey);
|
|
}
|
|
|
|
while (pElement)
|
|
{
|
|
CXTPMarkupResourceDictionary* pResources = MARKUP_STATICCAST(CXTPMarkupResourceDictionary, pElement->GetValue(CXTPMarkupStyle::m_pResourcesProperty));
|
|
|
|
if (pResources)
|
|
{
|
|
CXTPMarkupObject* pValue = pResources->Lookup(pKey);
|
|
if (pValue)
|
|
return pValue;
|
|
}
|
|
|
|
CXTPMarkupStyle* pStyle = MARKUP_STATICCAST(CXTPMarkupStyle, pElement->GetValue(CXTPMarkupFrameworkElement::m_pStyleProperty));
|
|
if (pStyle)
|
|
{
|
|
CXTPMarkupObject* pValue = pStyle->FindResource(pKey);
|
|
if (pValue)
|
|
return pValue;
|
|
}
|
|
|
|
if (pElement->GetType() == MARKUP_TYPE(CXTPMarkupStyle))
|
|
return NULL;
|
|
|
|
pElement = pElement->GetLogicalParent();
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// CXTPMarkupSetter
|
|
CXTPMarkupDependencyProperty* CXTPMarkupSetter::m_pPropertyProperty = NULL;
|
|
CXTPMarkupDependencyProperty* CXTPMarkupSetter::m_pValueProperty = NULL;
|
|
|
|
IMPLEMENT_MARKUPCLASS(L"Setter", CXTPMarkupSetter, CXTPMarkupObject);
|
|
|
|
void CXTPMarkupSetter::RegisterMarkupClass()
|
|
{
|
|
m_pPropertyProperty = CXTPMarkupDependencyProperty::Register(L"Property", MARKUP_TYPE(CXTPMarkupObject), MARKUP_TYPE(CXTPMarkupSetter));
|
|
m_pValueProperty = CXTPMarkupDependencyProperty::Register(L"Value", MARKUP_TYPE(CXTPMarkupObject), MARKUP_TYPE(CXTPMarkupSetter));
|
|
}
|
|
|
|
CXTPMarkupSetter::CXTPMarkupSetter()
|
|
{
|
|
|
|
}
|
|
|
|
CXTPMarkupSetter::CXTPMarkupSetter(CXTPMarkupDependencyProperty* pProperty, CXTPMarkupObject* pValue)
|
|
{
|
|
ASSERT(pProperty && pValue);
|
|
|
|
pProperty->AddRef();
|
|
SetValue(m_pPropertyProperty, pProperty);
|
|
SetValue(m_pValueProperty, pValue);
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// CXTPMarkupSetterColection
|
|
|
|
IMPLEMENT_MARKUPCLASS(NULL, CXTPMarkupSetterColection, CXTPMarkupCollection);
|
|
|
|
void CXTPMarkupSetterColection::RegisterMarkupClass()
|
|
{
|
|
|
|
}
|
|
|
|
CXTPMarkupSetterColection::CXTPMarkupSetterColection()
|
|
{
|
|
m_pElementType = MARKUP_TYPE(CXTPMarkupSetter);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// CXTPMarkupStyle
|
|
|
|
CXTPMarkupDependencyProperty* CXTPMarkupStyle::m_pTargetTypeProperty = NULL;
|
|
CXTPMarkupDependencyProperty* CXTPMarkupStyle::m_pBasedOnProperty = NULL;
|
|
CXTPMarkupDependencyProperty* CXTPMarkupStyle::m_pResourcesProperty = NULL;
|
|
CXTPMarkupDependencyProperty* CXTPMarkupStyle::m_pTriggersProperty = NULL;
|
|
|
|
IMPLEMENT_MARKUPCLASS(L"Style", CXTPMarkupStyle, CXTPMarkupObject)
|
|
|
|
void CXTPMarkupStyle::RegisterMarkupClass()
|
|
{
|
|
CXTPMarkupSetter::RegisterType();
|
|
CXTPMarkupTrigger::RegisterType();
|
|
|
|
m_pResourcesProperty = CXTPMarkupDependencyProperty::Register(L"Resources", MARKUP_TYPE(CXTPMarkupResourceDictionary), MARKUP_TYPE(CXTPMarkupStyle));
|
|
|
|
m_pTargetTypeProperty = CXTPMarkupDependencyProperty::Register(L"TargetType", MARKUP_TYPE(CXTPMarkupType), MARKUP_TYPE(CXTPMarkupStyle));
|
|
m_pBasedOnProperty = CXTPMarkupDependencyProperty::Register(L"BasedOn", MARKUP_TYPE(CXTPMarkupStyle), MARKUP_TYPE(CXTPMarkupStyle));
|
|
|
|
m_pTriggersProperty = CXTPMarkupDependencyProperty::Register(L"Triggers", MARKUP_TYPE(CXTPMarkupTriggerCollection), MARKUP_TYPE(CXTPMarkupStyle));
|
|
}
|
|
|
|
|
|
CXTPMarkupStyle::CXTPMarkupStyle()
|
|
{
|
|
m_pSetters = new CXTPMarkupSetterColection();
|
|
m_pSetters->SetLogicalParent(this);
|
|
|
|
m_bSealed = FALSE;
|
|
|
|
m_pProperties = NULL;
|
|
}
|
|
|
|
CXTPMarkupStyle::~CXTPMarkupStyle()
|
|
{
|
|
if (m_pSetters)
|
|
{
|
|
m_pSetters->SetLogicalParent(NULL);
|
|
MARKUP_RELEASE(m_pSetters);
|
|
}
|
|
|
|
MARKUP_RELEASE(m_pProperties);
|
|
}
|
|
|
|
|
|
void CXTPMarkupStyle::ResolveTriggerProperty(CXTPMarkupBuilder* pBuilder, CXTPMarkupTrigger* pTrigger)
|
|
{
|
|
ResolveSetterProperty(pBuilder, pTrigger);
|
|
|
|
CXTPMarkupSetterColection* pSetters = pTrigger->GetSetters();
|
|
int nCount = pSetters ? pSetters->GetCount() : 0;
|
|
|
|
for (int i = 0; i < nCount; i++)
|
|
{
|
|
ResolveSetterProperty(pBuilder, pSetters->GetItem(i));
|
|
}
|
|
}
|
|
|
|
void CXTPMarkupStyle::ResolveSetterProperty(CXTPMarkupBuilder* pBuilder, CXTPMarkupObject* pSetter)
|
|
{
|
|
CXTPMarkupType* pTargetType = MARKUP_STATICCAST(CXTPMarkupType, GetValue(m_pTargetTypeProperty));
|
|
|
|
CXTPMarkupDependencyProperty* pProperty = (CXTPMarkupDependencyProperty*)pSetter->GetValue(CXTPMarkupSetter::m_pPropertyProperty);
|
|
if (!pProperty)
|
|
{
|
|
pBuilder->ThrowBuilderException(_T("Must specify both Property and Value for Setter."));
|
|
}
|
|
|
|
if (pProperty->GetType() == MARKUP_TYPE(CXTPMarkupDependencyProperty))
|
|
{
|
|
|
|
}
|
|
else if (IsStringObject(pProperty))
|
|
{
|
|
LPCWSTR lpszTagName = *((CXTPMarkupString*)pProperty);
|
|
|
|
pProperty = pBuilder->FindProperty(pTargetType, lpszTagName);
|
|
|
|
if (pProperty == NULL)
|
|
{
|
|
pBuilder->ThrowBuilderException(pBuilder->FormatString(_T("Cannot find the Style Property '%ls'"), (LPCTSTR)lpszTagName));
|
|
}
|
|
|
|
pProperty->AddRef();
|
|
pSetter->SetValue(CXTPMarkupSetter::m_pPropertyProperty, pProperty);
|
|
}
|
|
else
|
|
{
|
|
pBuilder->ThrowBuilderException(_T("Must specify both Property and Value for Setter."));
|
|
}
|
|
|
|
CXTPMarkupObject* pValue = pSetter->GetValue(CXTPMarkupSetter::m_pValueProperty);
|
|
if (!pValue)
|
|
{
|
|
pBuilder->ThrowBuilderException(_T("Must specify both Property and Value for Setter."));
|
|
}
|
|
|
|
if (!pValue->IsKindOf(pProperty->GetPropetyType()))
|
|
{
|
|
CXTPMarkupObject* pNewValue = pBuilder->ConvertValue(pProperty, pValue);
|
|
pSetter->SetValue(CXTPMarkupSetter::m_pValueProperty, pNewValue);
|
|
}
|
|
|
|
}
|
|
|
|
void CXTPMarkupStyle::SetContentObject(CXTPMarkupBuilder* pBuilder, CXTPMarkupObject* pContent)
|
|
{
|
|
if (pContent->IsKindOf(MARKUP_TYPE(CXTPMarkupSetter)))
|
|
{
|
|
ResolveSetterProperty(pBuilder, (CXTPMarkupSetter*)pContent);
|
|
m_pSetters->SetContentObject(pBuilder, pContent);
|
|
}
|
|
else
|
|
{
|
|
CXTPMarkupObject::SetContentObject(pBuilder, pContent);
|
|
}
|
|
}
|
|
|
|
void CXTPMarkupStyle::SetPropertyObject(CXTPMarkupBuilder* pBuilder, CXTPMarkupDependencyProperty* pProperty, CXTPMarkupObject* pValue)
|
|
{
|
|
if (pProperty == m_pTriggersProperty)
|
|
{
|
|
if (pValue && pValue->IsKindOf(MARKUP_TYPE(CXTPMarkupTriggerCollection)))
|
|
{
|
|
CXTPMarkupTriggerCollection* pTriggers = (CXTPMarkupTriggerCollection*)pValue;
|
|
for (int i = 0; i < pTriggers->GetCount(); i++)
|
|
{
|
|
ResolveTriggerProperty(pBuilder, pTriggers->GetItem(i));
|
|
}
|
|
}
|
|
}
|
|
|
|
CXTPMarkupObject::SetPropertyObject(pBuilder, pProperty, pValue);
|
|
}
|
|
|
|
void CXTPMarkupStyle::Seal()
|
|
{
|
|
if (m_bSealed)
|
|
return;
|
|
|
|
ASSERT(!m_pProperties);
|
|
|
|
if (!m_pProperties)
|
|
m_pProperties = new CXTPMarkupProperties(NULL);
|
|
|
|
SetLogicalParent(NULL);
|
|
|
|
CXTPMarkupStyle* pStyle = GetBasedStyle();
|
|
if (pStyle)
|
|
{
|
|
pStyle->Seal();
|
|
|
|
m_pProperties->Copy(pStyle->m_pProperties);
|
|
}
|
|
|
|
|
|
int nCount = m_pSetters->GetCount();
|
|
for (int i = 0; i < nCount; i++)
|
|
{
|
|
CXTPMarkupSetter* pSetter = m_pSetters->GetItem(i);
|
|
|
|
CXTPMarkupObject* pValue = pSetter->GetSetterValue();
|
|
MARKUP_ADDREF(pValue);
|
|
|
|
m_pProperties->Set(pSetter->GetSetterProperty(), pValue);
|
|
}
|
|
|
|
|
|
m_bSealed = TRUE;
|
|
}
|
|
|
|
CXTPMarkupObject* CXTPMarkupStyle::GetStyleValue(CXTPMarkupDependencyProperty* pProperty) const
|
|
{
|
|
return m_pProperties ? m_pProperties->Lookup(pProperty) : NULL;
|
|
}
|
|
|
|
void CXTPMarkupType::SetTypeStyle(CXTPMarkupStyle* pStyle)
|
|
{
|
|
if (m_pTypeStyle)
|
|
{
|
|
m_pTypeStyle->Release();
|
|
}
|
|
|
|
m_pTypeStyle = pStyle;
|
|
|
|
if (pStyle)
|
|
{
|
|
pStyle->Seal();
|
|
}
|
|
}
|
|
|
|
CXTPMarkupObject* CXTPMarkupStyle::FindResource(const CXTPMarkupObject* pKey) const
|
|
{
|
|
return CXTPMarkupResourceDictionary::FindResource(this, pKey);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// CXTPMarkupTrigger
|
|
|
|
CXTPMarkupDependencyProperty* CXTPMarkupTrigger::m_pPropertyProperty = NULL;
|
|
CXTPMarkupDependencyProperty* CXTPMarkupTrigger::m_pSettersProperty = NULL;
|
|
CXTPMarkupDependencyProperty* CXTPMarkupTrigger::m_pValueProperty = NULL;
|
|
|
|
|
|
IMPLEMENT_MARKUPCLASS(L"Trigger", CXTPMarkupTrigger, CXTPMarkupObject)
|
|
|
|
void CXTPMarkupTrigger::RegisterMarkupClass()
|
|
{
|
|
CXTPMarkupSetter::RegisterType();
|
|
|
|
m_pPropertyProperty = CXTPMarkupSetter::m_pPropertyProperty->AddOwner(MARKUP_TYPE(CXTPMarkupTrigger));
|
|
m_pSettersProperty = CXTPMarkupDependencyProperty::Register(L"Setters", MARKUP_TYPE(CXTPMarkupSetterColection), MARKUP_TYPE(CXTPMarkupTrigger));
|
|
m_pValueProperty = CXTPMarkupSetter::m_pValueProperty->AddOwner(MARKUP_TYPE(CXTPMarkupTrigger));
|
|
}
|
|
|
|
CXTPMarkupTrigger::CXTPMarkupTrigger()
|
|
{
|
|
|
|
}
|
|
|
|
CXTPMarkupTrigger::CXTPMarkupTrigger(CXTPMarkupDependencyProperty* pProperty, CXTPMarkupObject* pValue)
|
|
{
|
|
ASSERT(pProperty && pValue);
|
|
|
|
pProperty->AddRef();
|
|
SetValue(m_pPropertyProperty, pProperty);
|
|
SetValue(m_pValueProperty, pValue);
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// CXTPMarkupTriggerCollection
|
|
IMPLEMENT_MARKUPCLASS(NULL, CXTPMarkupTriggerCollection, CXTPMarkupCollection)
|
|
|
|
void CXTPMarkupTriggerCollection::RegisterMarkupClass()
|
|
{
|
|
|
|
}
|
|
|
|
CXTPMarkupTriggerCollection::CXTPMarkupTriggerCollection()
|
|
{
|
|
m_pElementType = MARKUP_TYPE(CXTPMarkupTrigger);
|
|
}
|