MyGUI
3.2.0
|
00001 00006 /* 00007 This file is part of MyGUI. 00008 00009 MyGUI is free software: you can redistribute it and/or modify 00010 it under the terms of the GNU Lesser General Public License as published by 00011 the Free Software Foundation, either version 3 of the License, or 00012 (at your option) any later version. 00013 00014 MyGUI is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 GNU Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public License 00020 along with MyGUI. If not, see <http://www.gnu.org/licenses/>. 00021 */ 00022 #include "MyGUI_Precompiled.h" 00023 #include "MyGUI_ResourceSkin.h" 00024 #include "MyGUI_FactoryManager.h" 00025 #include "MyGUI_LanguageManager.h" 00026 00027 namespace MyGUI 00028 { 00029 00030 ResourceSkin::ResourceSkin() 00031 { 00032 } 00033 00034 ResourceSkin::~ResourceSkin() 00035 { 00036 for (MapWidgetStateInfo::iterator item = mStates.begin(); item != mStates.end(); ++ item) 00037 { 00038 for (VectorStateInfo::iterator info = (*item).second.begin(); info != (*item).second.end(); ++ info) 00039 delete (*info); 00040 } 00041 mStates.clear(); 00042 } 00043 00044 void ResourceSkin::deserialization(xml::ElementPtr _node, Version _version) 00045 { 00046 Base::deserialization(_node, _version); 00047 00048 // парсим атрибуты скина 00049 std::string name, texture, tmp; 00050 IntSize size; 00051 _node->findAttribute("name", name); 00052 _node->findAttribute("texture", texture); 00053 if (_node->findAttribute("size", tmp)) size = IntSize::parse(tmp); 00054 00055 LanguageManager& localizator = LanguageManager::getInstance(); 00056 00057 // вспомогательный класс для биндинга сабскинов 00058 SubWidgetBinding bind; 00059 00060 // поддержка замены тегов в скинах 00061 if (_version >= Version(1, 1)) 00062 { 00063 texture = localizator.replaceTags(texture); 00064 } 00065 00066 setInfo(size, texture); 00067 00068 // проверяем маску 00069 if (_node->findAttribute("mask", tmp)) 00070 addProperty("MaskPick", tmp); 00071 00072 // берем детей и крутимся, цикл с саб скинами 00073 xml::ElementEnumerator basis = _node->getElementEnumerator(); 00074 while (basis.next()) 00075 { 00076 if (basis->getName() == "Property") 00077 { 00078 // загружаем свойства 00079 std::string key, value; 00080 if (!basis->findAttribute("key", key)) continue; 00081 if (!basis->findAttribute("value", value)) continue; 00082 00083 // поддержка замены тегов в скинах 00084 if (_version >= Version(1, 1)) 00085 { 00086 value = localizator.replaceTags(value); 00087 } 00088 00089 // добавляем свойство 00090 addProperty(key, value); 00091 } 00092 else if (basis->getName() == "Child") 00093 { 00094 ChildSkinInfo child( 00095 basis->findAttribute("type"), 00096 WidgetStyle::parse(basis->findAttribute("style")), 00097 basis->findAttribute("skin"), 00098 IntCoord::parse(basis->findAttribute("offset")), 00099 Align::parse(basis->findAttribute("align")), 00100 basis->findAttribute("layer"), 00101 basis->findAttribute("name") 00102 ); 00103 00104 xml::ElementEnumerator child_params = basis->getElementEnumerator(); 00105 while (child_params.next("Property")) 00106 child.addParam(child_params->findAttribute("key"), child_params->findAttribute("value")); 00107 00108 addChild(child); 00109 //continue; 00110 } 00111 else if (basis->getName() == "BasisSkin") 00112 { 00113 // парсим атрибуты 00114 std::string basisSkinType, tmp_str; 00115 IntCoord offset; 00116 Align align = Align::Default; 00117 basis->findAttribute("type", basisSkinType); 00118 if (basis->findAttribute("offset", tmp_str)) offset = IntCoord::parse(tmp_str); 00119 if (basis->findAttribute("align", tmp_str)) align = Align::parse(tmp_str); 00120 00121 bind.create(offset, align, basisSkinType); 00122 00123 // берем детей и крутимся, цикл со стейтами 00124 xml::ElementEnumerator state = basis->getElementEnumerator(); 00125 00126 // проверяем на новый формат стейтов 00127 bool new_format = false; 00128 // если версия меньше 1.0 то переименовываем стейты 00129 if (_version < Version(1, 0)) 00130 { 00131 while (state.next()) 00132 { 00133 if (state->getName() == "State") 00134 { 00135 const std::string& name_state = state->findAttribute("name"); 00136 if ((name_state == "normal_checked") || (state->findAttribute("name") == "normal_check")) 00137 { 00138 new_format = true; 00139 break; 00140 } 00141 } 00142 } 00143 // обновляем 00144 state = basis->getElementEnumerator(); 00145 } 00146 00147 while (state.next()) 00148 { 00149 if (state->getName() == "State") 00150 { 00151 // парсим атрибуты стейта 00152 std::string basisStateName; 00153 state->findAttribute("name", basisStateName); 00154 00155 // если версия меньше 1.0 то переименовываем стейты 00156 if (_version < Version(1, 0)) 00157 { 00158 // это обсолет новых типов 00159 if (basisStateName == "disable_check") basisStateName = "disabled_checked"; 00160 else if (basisStateName == "normal_check") basisStateName = "normal_checked"; 00161 else if (basisStateName == "active_check") basisStateName = "highlighted_checked"; 00162 else if (basisStateName == "pressed_check") basisStateName = "pushed_checked"; 00163 else if (basisStateName == "disable") basisStateName = "disabled"; 00164 else if (basisStateName == "active") basisStateName = "highlighted"; 00165 else if (basisStateName == "select") basisStateName = "pushed"; 00166 else if (basisStateName == "pressed") 00167 { 00168 if (new_format) basisStateName = "pushed"; 00169 else basisStateName = "normal_checked"; 00170 } 00171 } 00172 00173 // конвертируем инфу о стейте 00174 IStateInfo* data = nullptr; 00175 IObject* object = FactoryManager::getInstance().createObject("BasisSkin/State", basisSkinType); 00176 if (object != nullptr) 00177 { 00178 data = object->castType<IStateInfo>(); 00179 data->deserialization(state.current(), _version); 00180 } 00181 00182 // добавляем инфо о стайте 00183 bind.add(basisStateName, data, name); 00184 } 00185 } 00186 00187 // теперь всё вместе добавляем в скин 00188 addInfo(bind); 00189 } 00190 00191 } 00192 } 00193 00194 void ResourceSkin::setInfo(const IntSize& _size, const std::string& _texture) 00195 { 00196 mSize = _size; 00197 mTexture = _texture; 00198 } 00199 00200 void ResourceSkin::addInfo(const SubWidgetBinding& _bind) 00201 { 00202 checkState(_bind.mStates); 00203 mBasis.push_back(SubWidgetInfo(_bind.mType, _bind.mOffset, _bind.mAlign)); 00204 checkBasis(); 00205 fillState(_bind.mStates, mBasis.size() - 1); 00206 } 00207 00208 void ResourceSkin::addProperty(const std::string& _key, const std::string& _value) 00209 { 00210 mProperties[_key] = _value; 00211 } 00212 00213 void ResourceSkin::addChild(const ChildSkinInfo& _child) 00214 { 00215 mChilds.push_back(_child); 00216 } 00217 00218 void ResourceSkin::clear() 00219 { 00220 for (MapWidgetStateInfo::iterator iter = mStates.begin(); iter != mStates.end(); ++iter) 00221 { 00222 for (VectorStateInfo::iterator iter2 = iter->second.begin(); iter2 != iter->second.end(); ++iter2) 00223 { 00224 delete *iter2; 00225 } 00226 } 00227 } 00228 00229 void ResourceSkin::checkState(const MapStateInfo& _states) 00230 { 00231 for (MapStateInfo::const_iterator iter = _states.begin(); iter != _states.end(); ++iter) 00232 { 00233 checkState(iter->first); 00234 } 00235 } 00236 00237 void ResourceSkin::checkState(const std::string& _name) 00238 { 00239 // ищем такой же ключ 00240 MapWidgetStateInfo::const_iterator iter = mStates.find(_name); 00241 if (iter == mStates.end()) 00242 { 00243 // добавляем новый стейт 00244 mStates[_name] = VectorStateInfo(); 00245 } 00246 } 00247 00248 void ResourceSkin::checkBasis() 00249 { 00250 // и увеличиваем размер смещений по колличеству сабвиджетов 00251 for (MapWidgetStateInfo::iterator iter = mStates.begin(); iter != mStates.end(); ++iter) 00252 { 00253 iter->second.resize(mBasis.size()); 00254 } 00255 } 00256 00257 void ResourceSkin::fillState(const MapStateInfo& _states, size_t _index) 00258 { 00259 for (MapStateInfo::const_iterator iter = _states.begin(); iter != _states.end(); ++iter) 00260 { 00261 mStates[iter->first][_index] = iter->second; 00262 } 00263 } 00264 00265 const IntSize& ResourceSkin::getSize() const 00266 { 00267 return mSize; 00268 } 00269 00270 const std::string& ResourceSkin::getTextureName() const 00271 { 00272 return mTexture; 00273 } 00274 00275 const VectorSubWidgetInfo& ResourceSkin::getBasisInfo() const 00276 { 00277 return mBasis; 00278 } 00279 00280 const MapWidgetStateInfo& ResourceSkin::getStateInfo() const 00281 { 00282 return mStates; 00283 } 00284 00285 const MapString& ResourceSkin::getProperties() const 00286 { 00287 return mProperties; 00288 } 00289 00290 const VectorChildSkinInfo& ResourceSkin::getChild() const 00291 { 00292 return mChilds; 00293 } 00294 00295 const std::string& ResourceSkin::getSkinName() const 00296 { 00297 return mSkinName; 00298 } 00299 00300 } // namespace MyGUI