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