1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-22 11:53:53 +00:00
openmw/extern/mygui_3.0.1/MyGUIEngine/src/MyGUI_ResourceSkin.cpp
2010-07-08 00:23:28 +02:00

266 lines
7.2 KiB
C++

/*!
@file
@author Albert Semenov
@date 26/2009
@module
*/
/*
This file is part of MyGUI.
MyGUI is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
MyGUI is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with MyGUI. If not, see <http://www.gnu.org/licenses/>.
*/
#include "MyGUI_Precompiled.h"
#include "MyGUI_ResourceSkin.h"
#include "MyGUI_FactoryManager.h"
#include "MyGUI_LanguageManager.h"
namespace MyGUI
{
ResourceSkin::ResourceSkin()
{
}
void ResourceSkin::deserialization(xml::ElementPtr _node, Version _version)
{
Base::deserialization(_node, _version);
// ïàðñèì àòðèáóòû ñêèíà
std::string name, texture, tmp;
IntSize size;
_node->findAttribute("name", name);
_node->findAttribute("texture", texture);
if (_node->findAttribute("size", tmp)) size = IntSize::parse(tmp);
LanguageManager& localizator = LanguageManager::getInstance();
// âñïîìîãàòåëüíûé êëàññ äëÿ áèíäèíãà ñàáñêèíîâ
SubWidgetBinding bind;
// ïîääåðæêà çàìåíû òåãîâ â ñêèíàõ
if (_version >= Version(1, 1))
{
texture = localizator.replaceTags(texture);
}
setInfo(size, texture);
// ïðîâåðÿåì ìàñêó
if (_node->findAttribute("mask", tmp))
{
if (!loadMask(tmp))
{
MYGUI_LOG(Error, "Skin: mask not load '" << tmp << "'");
}
}
// áåðåì äåòåé è êðóòèìñÿ, öèêë ñ ñàá ñêèíàìè
xml::ElementEnumerator basis = _node->getElementEnumerator();
while (basis.next())
{
if (basis->getName() == "Property")
{
// çàãðóæàåì ñâîéñòâà
std::string key, value;
if (!basis->findAttribute("key", key)) continue;
if (!basis->findAttribute("value", value)) continue;
// ïîääåðæêà çàìåíû òåãîâ â ñêèíàõ
if (_version >= Version(1, 1))
{
value = localizator.replaceTags(value);
}
// äîáàâëÿåì ñâîéñòâî
addProperty(key, value);
}
else if (basis->getName() == "Child")
{
ChildSkinInfo child(
basis->findAttribute("type"),
WidgetStyle::parse(basis->findAttribute("style")),
basis->findAttribute("skin"),
IntCoord::parse(basis->findAttribute("offset")),
Align::parse(basis->findAttribute("align")),
basis->findAttribute("layer"),
basis->findAttribute("name")
);
xml::ElementEnumerator child_params = basis->getElementEnumerator();
while (child_params.next("Property"))
child.addParam(child_params->findAttribute("key"), child_params->findAttribute("value"));
addChild(child);
//continue;
}
else if (basis->getName() == "BasisSkin")
{
// ïàðñèì àòðèáóòû
std::string basisSkinType, tmp_str;
IntCoord offset;
Align align = Align::Default;
basis->findAttribute("type", basisSkinType);
if (basis->findAttribute("offset", tmp_str)) offset = IntCoord::parse(tmp_str);
if (basis->findAttribute("align", tmp_str)) align = Align::parse(tmp_str);
bind.create(offset, align, basisSkinType);
// áåðåì äåòåé è êðóòèìñÿ, öèêë ñî ñòåéòàìè
xml::ElementEnumerator state = basis->getElementEnumerator();
// ïðîâåðÿåì íà íîâûé ôîðìàò ñòåéòîâ
bool new_format = false;
// åñëè âåðñèÿ ìåíüøå 1.0 òî ïåðåèìåíîâûâàåì ñòåéòû
if (_version < Version(1, 0))
{
while (state.next())
{
if (state->getName() == "State")
{
const std::string& name_state = state->findAttribute("name");
if ((name_state == "normal_checked") || (state->findAttribute("name") == "normal_check"))
{
new_format = true;
break;
}
}
}
// îáíîâëÿåì
state = basis->getElementEnumerator();
}
while (state.next())
{
if (state->getName() == "State")
{
// ïàðñèì àòðèáóòû ñòåéòà
std::string basisStateName;
state->findAttribute("name", basisStateName);
// åñëè âåðñèÿ ìåíüøå 1.0 òî ïåðåèìåíîâûâàåì ñòåéòû
if (_version < Version(1, 0))
{
// ýòî îáñîëåò íîâûõ òèïîâ
if (basisStateName == "disable_check") basisStateName = "disabled_checked";
else if (basisStateName == "normal_check") basisStateName = "normal_checked";
else if (basisStateName == "active_check") basisStateName = "highlighted_checked";
else if (basisStateName == "pressed_check") basisStateName = "pushed_checked";
else if (basisStateName == "disable") basisStateName = "disabled";
else if (basisStateName == "active") basisStateName = "highlighted";
else if (basisStateName == "select") basisStateName = "pushed";
else if (basisStateName == "pressed")
{
if (new_format) basisStateName = "pushed";
else basisStateName = "normal_checked";
}
}
// êîíâåðòèðóåì èíôó î ñòåéòå
IStateInfo* data = nullptr;
IObject* object = FactoryManager::getInstance().createObject("BasisSkin/State", basisSkinType);
if (object != nullptr)
{
data = object->castType<IStateInfo>();
data->deserialization(state.current(), _version);
}
// äîáàâëÿåì èíôî î ñòàéòå
bind.add(basisStateName, data, name);
}
}
// òåïåðü âñ¸ âìåñòå äîáàâëÿåì â ñêèí
addInfo(bind);
}
}
}
void ResourceSkin::setInfo(const IntSize& _size, const std::string &_texture)
{
mSize = _size;
mTexture = _texture;
}
void ResourceSkin::addInfo(const SubWidgetBinding& _bind)
{
checkState(_bind.mStates);
mBasis.push_back(SubWidgetInfo(_bind.mType, _bind.mOffset, _bind.mAlign));
checkBasis();
fillState(_bind.mStates, mBasis.size()-1);
}
void ResourceSkin::addProperty(const std::string &_key, const std::string &_value)
{
mProperties[_key] = _value;
}
void ResourceSkin::addChild(const ChildSkinInfo& _child)
{
mChilds.push_back(_child);
}
bool ResourceSkin::loadMask(const std::string& _file)
{
return mMaskPeek.load(_file);
}
void ResourceSkin::clear()
{
for (MapWidgetStateInfo::iterator iter = mStates.begin(); iter!=mStates.end(); ++iter)
{
for (VectorStateInfo::iterator iter2=iter->second.begin(); iter2!=iter->second.end(); ++iter2)
{
delete *iter2;
}
}
}
void ResourceSkin::checkState(const MapStateInfo& _states)
{
for (MapStateInfo::const_iterator iter = _states.begin(); iter != _states.end(); ++iter)
{
checkState(iter->first);
}
}
void ResourceSkin::checkState(const std::string& _name)
{
// èùåì òàêîé æå êëþ÷
MapWidgetStateInfo::const_iterator iter = mStates.find(_name);
if (iter == mStates.end())
{
// äîáàâëÿåì íîâûé ñòåéò
mStates[_name] = VectorStateInfo();
}
}
void ResourceSkin::checkBasis()
{
// è óâåëè÷èâàåì ðàçìåð ñìåùåíèé ïî êîëëè÷åñòâó ñàáâèäæåòîâ
for (MapWidgetStateInfo::iterator iter = mStates.begin(); iter!=mStates.end(); ++iter)
{
iter->second.resize(mBasis.size());
}
}
void ResourceSkin::fillState(const MapStateInfo& _states, size_t _index)
{
for (MapStateInfo::const_iterator iter = _states.begin(); iter != _states.end(); ++iter)
{
mStates[iter->first][_index] = iter->second;
}
}
} // namespace MyGUI