MyGUI  3.2.1
MyGUI_ResourceSkin.cpp
Go to the documentation of this file.
1 /*
2  * This source file is part of MyGUI. For the latest info, see http://mygui.info/
3  * Distributed under the MIT License
4  * (See accompanying file COPYING.MIT or copy at http://opensource.org/licenses/MIT)
5  */
6 
7 #include "MyGUI_Precompiled.h"
8 #include "MyGUI_ResourceSkin.h"
9 #include "MyGUI_FactoryManager.h"
10 #include "MyGUI_LanguageManager.h"
11 #include "MyGUI_SubWidgetManager.h"
12 
13 namespace MyGUI
14 {
15 
17  {
18  }
19 
21  {
22  for (MapWidgetStateInfo::iterator item = mStates.begin(); item != mStates.end(); ++ item)
23  {
24  for (VectorStateInfo::iterator info = (*item).second.begin(); info != (*item).second.end(); ++ info)
25  delete (*info);
26  }
27  mStates.clear();
28  }
29 
31  {
32  Base::deserialization(_node, _version);
33 
34  std::string stateCategory = SubWidgetManager::getInstance().getStateCategoryName();
35 
36  // парсим атрибуты скина
37  std::string name, texture, tmp;
38  IntSize size;
39  _node->findAttribute("name", name);
40  _node->findAttribute("texture", texture);
41  if (_node->findAttribute("size", tmp)) size = IntSize::parse(tmp);
42 
44 
45  // вспомогательный класс для биндинга сабскинов
46  SubWidgetBinding bind;
47 
48  // tags replacement support for Skins
49  if (_version >= Version(1, 1))
50  {
51  texture = localizator.replaceTags(texture);
52  }
53 
54  setInfo(size, texture);
55 
56  // проверяем маску
57  if (_node->findAttribute("mask", tmp))
58  addProperty("MaskPick", tmp);
59 
60  // берем детей и крутимся, цикл с саб скинами
62  while (basis.next())
63  {
64  if (basis->getName() == "Property")
65  {
66  // загружаем свойства
67  std::string key, value;
68  if (!basis->findAttribute("key", key))
69  continue;
70  if (!basis->findAttribute("value", value))
71  continue;
72 
73  // tags replacement support for Skins
74  if (_version >= Version(1, 1))
75  {
76  value = localizator.replaceTags(value);
77  }
78 
79  // добавляем свойство
80  addProperty(key, value);
81  }
82  else if (basis->getName() == "Child")
83  {
84  ChildSkinInfo child(
85  basis->findAttribute("type"),
86  WidgetStyle::parse(basis->findAttribute("style")),
87  basis->findAttribute("skin"),
88  IntCoord::parse(basis->findAttribute("offset")),
89  Align::parse(basis->findAttribute("align")),
90  basis->findAttribute("layer"),
91  basis->findAttribute("name"));
92 
93  xml::ElementEnumerator child_params = basis->getElementEnumerator();
94  while (child_params.next("Property"))
95  child.addParam(child_params->findAttribute("key"), child_params->findAttribute("value"));
96 
97  addChild(child);
98  //continue;
99  }
100  else if (basis->getName() == "BasisSkin")
101  {
102  // парсим атрибуты
103  std::string basisSkinType, tmp_str;
104  IntCoord offset;
105  Align align = Align::Default;
106  basis->findAttribute("type", basisSkinType);
107  if (basis->findAttribute("offset", tmp_str))
108  offset = IntCoord::parse(tmp_str);
109  if (basis->findAttribute("align", tmp_str))
110  align = Align::parse(tmp_str);
111 
112  bind.create(offset, align, basisSkinType);
113 
114  // берем детей и крутимся, цикл со стейтами
116 
117  // проверяем на новый формат стейтов
118  bool new_format = false;
119  // если версия меньше 1.0 то переименовываем стейты
120  if (_version < Version(1, 0))
121  {
122  while (state.next())
123  {
124  if (state->getName() == "State")
125  {
126  const std::string& name_state = state->findAttribute("name");
127  if ((name_state == "normal_checked") || (state->findAttribute("name") == "normal_check"))
128  {
129  new_format = true;
130  break;
131  }
132  }
133  }
134  // обновляем
135  state = basis->getElementEnumerator();
136  }
137 
138  while (state.next())
139  {
140  if (state->getName() == "State")
141  {
142  // парсим атрибуты стейта
143  std::string basisStateName;
144  state->findAttribute("name", basisStateName);
145 
146  // если версия меньше 1.0 то переименовываем стейты
147  if (_version < Version(1, 0))
148  {
149  // это обсолет новых типов
150  if (basisStateName == "disable_check")
151  basisStateName = "disabled_checked";
152  else if (basisStateName == "normal_check")
153  basisStateName = "normal_checked";
154  else if (basisStateName == "active_check")
155  basisStateName = "highlighted_checked";
156  else if (basisStateName == "pressed_check")
157  basisStateName = "pushed_checked";
158  else if (basisStateName == "disable")
159  basisStateName = "disabled";
160  else if (basisStateName == "active")
161  basisStateName = "highlighted";
162  else if (basisStateName == "select")
163  basisStateName = "pushed";
164  else if (basisStateName == "pressed")
165  {
166  if (new_format)
167  basisStateName = "pushed";
168  else
169  basisStateName = "normal_checked";
170  }
171  }
172 
173  // конвертируем инфу о стейте
174  IStateInfo* data = nullptr;
175  IObject* object = FactoryManager::getInstance().createObject(stateCategory, basisSkinType);
176  if (object != nullptr)
177  {
178  data = object->castType<IStateInfo>();
179  data->deserialization(state.current(), _version);
180  }
181 
182  // добавляем инфо о стайте
183  bind.add(basisStateName, data, name);
184  }
185  }
186 
187  // теперь всё вместе добавляем в скин
188  addInfo(bind);
189  }
190 
191  }
192  }
193 
194  void ResourceSkin::setInfo(const IntSize& _size, const std::string& _texture)
195  {
196  mSize = _size;
197  mTexture = _texture;
198  }
199 
200  void ResourceSkin::addInfo(const SubWidgetBinding& _bind)
201  {
202  checkState(_bind.mStates);
203  mBasis.push_back(SubWidgetInfo(_bind.mType, _bind.mOffset, _bind.mAlign));
204  checkBasis();
205  fillState(_bind.mStates, mBasis.size() - 1);
206  }
207 
208  void ResourceSkin::addProperty(const std::string& _key, const std::string& _value)
209  {
210  mProperties[_key] = _value;
211  }
212 
213  void ResourceSkin::addChild(const ChildSkinInfo& _child)
214  {
215  mChilds.push_back(_child);
216  }
217 
218  void ResourceSkin::clear()
219  {
220  for (MapWidgetStateInfo::iterator iter = mStates.begin(); iter != mStates.end(); ++iter)
221  {
222  for (VectorStateInfo::iterator iter2 = iter->second.begin(); iter2 != iter->second.end(); ++iter2)
223  {
224  delete *iter2;
225  }
226  }
227  }
228 
229  void ResourceSkin::checkState(const MapStateInfo& _states)
230  {
231  for (MapStateInfo::const_iterator iter = _states.begin(); iter != _states.end(); ++iter)
232  {
233  checkState(iter->first);
234  }
235  }
236 
237  void ResourceSkin::checkState(const std::string& _name)
238  {
239  // ищем такой же ключ
240  MapWidgetStateInfo::const_iterator iter = mStates.find(_name);
241  if (iter == mStates.end())
242  {
243  // добавляем новый стейт
244  mStates[_name] = VectorStateInfo();
245  }
246  }
247 
248  void ResourceSkin::checkBasis()
249  {
250  // и увеличиваем размер смещений по колличеству сабвиджетов
251  for (MapWidgetStateInfo::iterator iter = mStates.begin(); iter != mStates.end(); ++iter)
252  {
253  iter->second.resize(mBasis.size());
254  }
255  }
256 
257  void ResourceSkin::fillState(const MapStateInfo& _states, size_t _index)
258  {
259  for (MapStateInfo::const_iterator iter = _states.begin(); iter != _states.end(); ++iter)
260  {
261  mStates[iter->first][_index] = iter->second;
262  }
263  }
264 
266  {
267  return mSize;
268  }
269 
270  const std::string& ResourceSkin::getTextureName() const
271  {
272  return mTexture;
273  }
274 
276  {
277  return mBasis;
278  }
279 
281  {
282  return mStates;
283  }
284 
286  {
287  return mProperties;
288  }
289 
291  {
292  return mChilds;
293  }
294 
295  const std::string& ResourceSkin::getSkinName() const
296  {
297  return mSkinName;
298  }
299 
300 } // namespace MyGUI