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++

// 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);
}