MyGUI 3.0.1
|
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 void ResourceSkin::deserialization(xml::ElementPtr _node, Version _version) 00036 { 00037 Base::deserialization(_node, _version); 00038 00039 // парсим атрибуты скина 00040 std::string name, texture, tmp; 00041 IntSize size; 00042 _node->findAttribute("name", name); 00043 _node->findAttribute("texture", texture); 00044 if (_node->findAttribute("size", tmp)) size = IntSize::parse(tmp); 00045 00046 LanguageManager& localizator = LanguageManager::getInstance(); 00047 00048 // вспомогательный класс для биндинга сабскинов 00049 SubWidgetBinding bind; 00050 00051 // поддержка замены тегов в скинах 00052 if (_version >= Version(1, 1)) 00053 { 00054 texture = localizator.replaceTags(texture); 00055 } 00056 00057 setInfo(size, texture); 00058 00059 // проверяем маску 00060 if (_node->findAttribute("mask", tmp)) 00061 { 00062 if (!loadMask(tmp)) 00063 { 00064 MYGUI_LOG(Error, "Skin: mask not load '" << tmp << "'"); 00065 } 00066 } 00067 00068 // берем детей и крутимся, цикл с саб скинами 00069 xml::ElementEnumerator basis = _node->getElementEnumerator(); 00070 while (basis.next()) 00071 { 00072 if (basis->getName() == "Property") 00073 { 00074 // загружаем свойства 00075 std::string key, value; 00076 if (!basis->findAttribute("key", key)) continue; 00077 if (!basis->findAttribute("value", value)) continue; 00078 00079 // поддержка замены тегов в скинах 00080 if (_version >= Version(1, 1)) 00081 { 00082 value = localizator.replaceTags(value); 00083 } 00084 00085 // добавляем свойство 00086 addProperty(key, value); 00087 } 00088 else if (basis->getName() == "Child") 00089 { 00090 ChildSkinInfo child( 00091 basis->findAttribute("type"), 00092 WidgetStyle::parse(basis->findAttribute("style")), 00093 basis->findAttribute("skin"), 00094 IntCoord::parse(basis->findAttribute("offset")), 00095 Align::parse(basis->findAttribute("align")), 00096 basis->findAttribute("layer"), 00097 basis->findAttribute("name") 00098 ); 00099 00100 xml::ElementEnumerator child_params = basis->getElementEnumerator(); 00101 while (child_params.next("Property")) 00102 child.addParam(child_params->findAttribute("key"), child_params->findAttribute("value")); 00103 00104 addChild(child); 00105 //continue; 00106 } 00107 else if (basis->getName() == "BasisSkin") 00108 { 00109 // парсим атрибуты 00110 std::string basisSkinType, tmp_str; 00111 IntCoord offset; 00112 Align align = Align::Default; 00113 basis->findAttribute("type", basisSkinType); 00114 if (basis->findAttribute("offset", tmp_str)) offset = IntCoord::parse(tmp_str); 00115 if (basis->findAttribute("align", tmp_str)) align = Align::parse(tmp_str); 00116 00117 bind.create(offset, align, basisSkinType); 00118 00119 // берем детей и крутимся, цикл со стейтами 00120 xml::ElementEnumerator state = basis->getElementEnumerator(); 00121 00122 // проверяем на новый формат стейтов 00123 bool new_format = false; 00124 // если версия меньше 1.0 то переименовываем стейты 00125 if (_version < Version(1, 0)) 00126 { 00127 while (state.next()) 00128 { 00129 if (state->getName() == "State") 00130 { 00131 const std::string& name_state = state->findAttribute("name"); 00132 if ((name_state == "normal_checked") || (state->findAttribute("name") == "normal_check")) 00133 { 00134 new_format = true; 00135 break; 00136 } 00137 } 00138 } 00139 // обновляем 00140 state = basis->getElementEnumerator(); 00141 } 00142 00143 while (state.next()) 00144 { 00145 if (state->getName() == "State") 00146 { 00147 // парсим атрибуты стейта 00148 std::string basisStateName; 00149 state->findAttribute("name", basisStateName); 00150 00151 // если версия меньше 1.0 то переименовываем стейты 00152 if (_version < Version(1, 0)) 00153 { 00154 // это обсолет новых типов 00155 if (basisStateName == "disable_check") basisStateName = "disabled_checked"; 00156 else if (basisStateName == "normal_check") basisStateName = "normal_checked"; 00157 else if (basisStateName == "active_check") basisStateName = "highlighted_checked"; 00158 else if (basisStateName == "pressed_check") basisStateName = "pushed_checked"; 00159 else if (basisStateName == "disable") basisStateName = "disabled"; 00160 else if (basisStateName == "active") basisStateName = "highlighted"; 00161 else if (basisStateName == "select") basisStateName = "pushed"; 00162 else if (basisStateName == "pressed") 00163 { 00164 if (new_format) basisStateName = "pushed"; 00165 else basisStateName = "normal_checked"; 00166 } 00167 } 00168 00169 // конвертируем инфу о стейте 00170 IStateInfo* data = nullptr; 00171 IObject* object = FactoryManager::getInstance().createObject("BasisSkin/State", basisSkinType); 00172 if (object != nullptr) 00173 { 00174 data = object->castType<IStateInfo>(); 00175 data->deserialization(state.current(), _version); 00176 } 00177 00178 // добавляем инфо о стайте 00179 bind.add(basisStateName, data, name); 00180 } 00181 } 00182 00183 // теперь всё вместе добавляем в скин 00184 addInfo(bind); 00185 } 00186 00187 } 00188 } 00189 00190 void ResourceSkin::setInfo(const IntSize& _size, const std::string &_texture) 00191 { 00192 mSize = _size; 00193 mTexture = _texture; 00194 } 00195 00196 void ResourceSkin::addInfo(const SubWidgetBinding& _bind) 00197 { 00198 checkState(_bind.mStates); 00199 mBasis.push_back(SubWidgetInfo(_bind.mType, _bind.mOffset, _bind.mAlign)); 00200 checkBasis(); 00201 fillState(_bind.mStates, mBasis.size()-1); 00202 } 00203 00204 void ResourceSkin::addProperty(const std::string &_key, const std::string &_value) 00205 { 00206 mProperties[_key] = _value; 00207 } 00208 00209 void ResourceSkin::addChild(const ChildSkinInfo& _child) 00210 { 00211 mChilds.push_back(_child); 00212 } 00213 00214 bool ResourceSkin::loadMask(const std::string& _file) 00215 { 00216 return mMaskPeek.load(_file); 00217 } 00218 00219 void ResourceSkin::clear() 00220 { 00221 for (MapWidgetStateInfo::iterator iter = mStates.begin(); iter!=mStates.end(); ++iter) 00222 { 00223 for (VectorStateInfo::iterator iter2=iter->second.begin(); iter2!=iter->second.end(); ++iter2) 00224 { 00225 delete *iter2; 00226 } 00227 } 00228 } 00229 00230 void ResourceSkin::checkState(const MapStateInfo& _states) 00231 { 00232 for (MapStateInfo::const_iterator iter = _states.begin(); iter != _states.end(); ++iter) 00233 { 00234 checkState(iter->first); 00235 } 00236 } 00237 00238 void ResourceSkin::checkState(const std::string& _name) 00239 { 00240 // ищем такой же ключ 00241 MapWidgetStateInfo::const_iterator iter = mStates.find(_name); 00242 if (iter == mStates.end()) 00243 { 00244 // добавляем новый стейт 00245 mStates[_name] = VectorStateInfo(); 00246 } 00247 } 00248 00249 void ResourceSkin::checkBasis() 00250 { 00251 // и увеличиваем размер смещений по колличеству сабвиджетов 00252 for (MapWidgetStateInfo::iterator iter = mStates.begin(); iter!=mStates.end(); ++iter) 00253 { 00254 iter->second.resize(mBasis.size()); 00255 } 00256 } 00257 00258 void ResourceSkin::fillState(const MapStateInfo& _states, size_t _index) 00259 { 00260 for (MapStateInfo::const_iterator iter = _states.begin(); iter != _states.end(); ++iter) 00261 { 00262 mStates[iter->first][_index] = iter->second; 00263 } 00264 } 00265 00266 } // namespace MyGUI