MyGUI
3.2.1
|
00001 /* 00002 * This source file is part of MyGUI. For the latest info, see http://mygui.info/ 00003 * Distributed under the MIT License 00004 * (See accompanying file COPYING.MIT or copy at http://opensource.org/licenses/MIT) 00005 */ 00006 00007 #include "MyGUI_Precompiled.h" 00008 #include "MyGUI_ResourceSkin.h" 00009 #include "MyGUI_FactoryManager.h" 00010 #include "MyGUI_LanguageManager.h" 00011 #include "MyGUI_SubWidgetManager.h" 00012 00013 namespace MyGUI 00014 { 00015 00016 ResourceSkin::ResourceSkin() 00017 { 00018 } 00019 00020 ResourceSkin::~ResourceSkin() 00021 { 00022 for (MapWidgetStateInfo::iterator item = mStates.begin(); item != mStates.end(); ++ item) 00023 { 00024 for (VectorStateInfo::iterator info = (*item).second.begin(); info != (*item).second.end(); ++ info) 00025 delete (*info); 00026 } 00027 mStates.clear(); 00028 } 00029 00030 void ResourceSkin::deserialization(xml::ElementPtr _node, Version _version) 00031 { 00032 Base::deserialization(_node, _version); 00033 00034 std::string stateCategory = SubWidgetManager::getInstance().getStateCategoryName(); 00035 00036 // парсим атрибуты скина 00037 std::string name, texture, tmp; 00038 IntSize size; 00039 _node->findAttribute("name", name); 00040 _node->findAttribute("texture", texture); 00041 if (_node->findAttribute("size", tmp)) size = IntSize::parse(tmp); 00042 00043 LanguageManager& localizator = LanguageManager::getInstance(); 00044 00045 // вспомогательный класс для биндинга сабскинов 00046 SubWidgetBinding bind; 00047 00048 // tags replacement support for Skins 00049 if (_version >= Version(1, 1)) 00050 { 00051 texture = localizator.replaceTags(texture); 00052 } 00053 00054 setInfo(size, texture); 00055 00056 // проверяем маску 00057 if (_node->findAttribute("mask", tmp)) 00058 addProperty("MaskPick", tmp); 00059 00060 // берем детей и крутимся, цикл с саб скинами 00061 xml::ElementEnumerator basis = _node->getElementEnumerator(); 00062 while (basis.next()) 00063 { 00064 if (basis->getName() == "Property") 00065 { 00066 // загружаем свойства 00067 std::string key, value; 00068 if (!basis->findAttribute("key", key)) 00069 continue; 00070 if (!basis->findAttribute("value", value)) 00071 continue; 00072 00073 // tags replacement support for Skins 00074 if (_version >= Version(1, 1)) 00075 { 00076 value = localizator.replaceTags(value); 00077 } 00078 00079 // добавляем свойство 00080 addProperty(key, value); 00081 } 00082 else if (basis->getName() == "Child") 00083 { 00084 ChildSkinInfo child( 00085 basis->findAttribute("type"), 00086 WidgetStyle::parse(basis->findAttribute("style")), 00087 basis->findAttribute("skin"), 00088 IntCoord::parse(basis->findAttribute("offset")), 00089 Align::parse(basis->findAttribute("align")), 00090 basis->findAttribute("layer"), 00091 basis->findAttribute("name")); 00092 00093 xml::ElementEnumerator child_params = basis->getElementEnumerator(); 00094 while (child_params.next("Property")) 00095 child.addParam(child_params->findAttribute("key"), child_params->findAttribute("value")); 00096 00097 addChild(child); 00098 //continue; 00099 } 00100 else if (basis->getName() == "BasisSkin") 00101 { 00102 // парсим атрибуты 00103 std::string basisSkinType, tmp_str; 00104 IntCoord offset; 00105 Align align = Align::Default; 00106 basis->findAttribute("type", basisSkinType); 00107 if (basis->findAttribute("offset", tmp_str)) 00108 offset = IntCoord::parse(tmp_str); 00109 if (basis->findAttribute("align", tmp_str)) 00110 align = Align::parse(tmp_str); 00111 00112 bind.create(offset, align, basisSkinType); 00113 00114 // берем детей и крутимся, цикл со стейтами 00115 xml::ElementEnumerator state = basis->getElementEnumerator(); 00116 00117 // проверяем на новый формат стейтов 00118 bool new_format = false; 00119 // если версия меньше 1.0 то переименовываем стейты 00120 if (_version < Version(1, 0)) 00121 { 00122 while (state.next()) 00123 { 00124 if (state->getName() == "State") 00125 { 00126 const std::string& name_state = state->findAttribute("name"); 00127 if ((name_state == "normal_checked") || (state->findAttribute("name") == "normal_check")) 00128 { 00129 new_format = true; 00130 break; 00131 } 00132 } 00133 } 00134 // обновляем 00135 state = basis->getElementEnumerator(); 00136 } 00137 00138 while (state.next()) 00139 { 00140 if (state->getName() == "State") 00141 { 00142 // парсим атрибуты стейта 00143 std::string basisStateName; 00144 state->findAttribute("name", basisStateName); 00145 00146 // если версия меньше 1.0 то переименовываем стейты 00147 if (_version < Version(1, 0)) 00148 { 00149 // это обсолет новых типов 00150 if (basisStateName == "disable_check") 00151 basisStateName = "disabled_checked"; 00152 else if (basisStateName == "normal_check") 00153 basisStateName = "normal_checked"; 00154 else if (basisStateName == "active_check") 00155 basisStateName = "highlighted_checked"; 00156 else if (basisStateName == "pressed_check") 00157 basisStateName = "pushed_checked"; 00158 else if (basisStateName == "disable") 00159 basisStateName = "disabled"; 00160 else if (basisStateName == "active") 00161 basisStateName = "highlighted"; 00162 else if (basisStateName == "select") 00163 basisStateName = "pushed"; 00164 else if (basisStateName == "pressed") 00165 { 00166 if (new_format) 00167 basisStateName = "pushed"; 00168 else 00169 basisStateName = "normal_checked"; 00170 } 00171 } 00172 00173 // конвертируем инфу о стейте 00174 IStateInfo* data = nullptr; 00175 IObject* object = FactoryManager::getInstance().createObject(stateCategory, 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