MyGUI  3.2.1
MyGUI_PointerManager.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_PointerManager.h"
10 #include "MyGUI_LayerManager.h"
11 #include "MyGUI_CoordConverter.h"
12 #include "MyGUI_WidgetManager.h"
13 #include "MyGUI_XmlDocument.h"
14 #include "MyGUI_Widget.h"
15 #include "MyGUI_FactoryManager.h"
16 #include "MyGUI_InputManager.h"
17 #include "MyGUI_Gui.h"
18 
21 
22 namespace MyGUI
23 {
24 
25  template <> PointerManager* Singleton<PointerManager>::msInstance = nullptr;
26  template <> const char* Singleton<PointerManager>::mClassTypeName = "PointerManager";
27 
29  mVisible(false),
30  mWidgetOwner(nullptr),
31  mMousePointer(nullptr),
32  mPointer(nullptr),
33  mIsInitialise(false),
34  mXmlPointerTagName("Pointer"),
35  mXmlPropertyTagName("Property"),
36  mXmlDefaultPointerValue("Default")
37  {
38  }
39 
41  {
42  MYGUI_ASSERT(!mIsInitialise, getClassTypeName() << " initialised twice");
43  MYGUI_LOG(Info, "* Initialise: " << getClassTypeName());
44 
45  Gui::getInstance().eventFrameStart += newDelegate(this, &PointerManager::notifyFrameStart);
46  InputManager::getInstance().eventChangeMouseFocus += newDelegate(this, &PointerManager::notifyChangeMouseFocus);
48 
49  ResourceManager::getInstance().registerLoadXmlDelegate(mXmlPointerTagName) = newDelegate(this, &PointerManager::_load);
50 
51  std::string resourceCategory = ResourceManager::getInstance().getCategoryName();
54 
55  mPointer = nullptr;
56  mMousePointer = nullptr;
57  mWidgetOwner = nullptr;
58  mVisible = true;
59 
60  mSkinName = "ImageBox";
61 
62  MYGUI_LOG(Info, getClassTypeName() << " successfully initialized");
63  mIsInitialise = true;
64  }
65 
67  {
68  MYGUI_ASSERT(mIsInitialise, getClassTypeName() << " is not initialised");
69  MYGUI_LOG(Info, "* Shutdown: " << getClassTypeName());
70 
71  InputManager::getInstance().eventChangeMouseFocus -= newDelegate(this, &PointerManager::notifyChangeMouseFocus);
72  Gui::getInstance().eventFrameStart -= newDelegate(this, &PointerManager::notifyFrameStart);
73 
74  std::string resourceCategory = ResourceManager::getInstance().getCategoryName();
77 
78  // удаляем все виджеты
79  _destroyAllChildWidget();
80 
81  mWidgetOwner = nullptr;
82 
85 
86  MYGUI_LOG(Info, getClassTypeName() << " successfully shutdown");
87  mIsInitialise = false;
88  }
89 
90  void PointerManager::_load(xml::ElementPtr _node, const std::string& _file, Version _version)
91  {
92 #ifndef MYGUI_DONT_USE_OBSOLETE
93  loadOldPointerFormat(_node, _file, _version, mXmlPointerTagName);
94 #endif // MYGUI_DONT_USE_OBSOLETE
95 
97  while (node.next())
98  {
99  if (node->getName() == mXmlPropertyTagName)
100  {
101  const std::string& key = node->findAttribute("key");
102  const std::string& value = node->findAttribute("value");
103  if (key == "Default")
104  setDefaultPointer(value);
105  else if (key == "Layer")
106  setLayerName(value);
107  else if (key == "Skin")
108  mSkinName = value;
109  }
110  }
111  }
112 
113  void PointerManager::notifyFrameStart(float _time)
114  {
116  if (mOldPoint != mPoint)
117  {
118  mOldPoint = mPoint;
119 
120  if (nullptr != mMousePointer && mPointer != nullptr)
121  mPointer->setPosition(mMousePointer, mPoint);
122  }
123  }
124 
125  void PointerManager::setVisible(bool _visible)
126  {
127  if (nullptr != mMousePointer) mMousePointer->setVisible(_visible);
128  mVisible = _visible;
129  }
130 
131  void PointerManager::setPointer(const std::string& _name, Widget* _owner)
132  {
133  if (nullptr == mMousePointer)
134  return;
135 
136  IResource* result = getByName(_name);
137  if (result == nullptr)
138  {
139  mPointer = nullptr;
140  mMousePointer->setVisible(false);
141  return;
142  }
143 
144  mMousePointer->setVisible(mVisible);
145  mPointer = result->castType<IPointer>();
146  mPointer->setImage(mMousePointer);
147  mPointer->setPosition(mMousePointer, mPoint);
148 
149  mWidgetOwner = _owner;
150  }
151 
152  void PointerManager::_unlinkWidget(Widget* _widget)
153  {
154  if (_widget == mWidgetOwner) setPointer(mDefaultName, nullptr);
155  else if (_widget == mMousePointer) mMousePointer = nullptr;
156  }
157 
159  {
160  setPointer(mDefaultName, nullptr);
161  }
162 
163  // создает виджет
164  Widget* PointerManager::baseCreateWidget(WidgetStyle _style, const std::string& _type, const std::string& _skin, const IntCoord& _coord, Align _align, const std::string& _layer, const std::string& _name)
165  {
166  Widget* widget = WidgetManager::getInstance().createWidget(_style, _type, _skin, _coord, /*_align, */nullptr, nullptr, /*this, */_name);
167  mWidgetChild.push_back(widget);
168 
169  widget->setAlign(_align);
170 
171  // присоединяем виджет с уровню
172  if (!_layer.empty())
174  return widget;
175  }
176 
177  // удяляет неудачника
178  void PointerManager::_destroyChildWidget(Widget* _widget)
179  {
180  MYGUI_ASSERT(nullptr != _widget, "invalid widget pointer");
181 
182  VectorWidgetPtr::iterator iter = std::find(mWidgetChild.begin(), mWidgetChild.end(), _widget);
183  if (iter != mWidgetChild.end())
184  {
185  // сохраняем указатель
186  MyGUI::Widget* widget = *iter;
187 
188  // удаляем из списка
189  mWidgetChild.erase(iter);
190 
191  // отписываем от всех
193 
194  // непосредственное удаление
196  }
197  else
198  {
199  MYGUI_EXCEPT("Widget '" << _widget->getName() << "' not found");
200  }
201  }
202 
203  // удаляет всех детей
204  void PointerManager::_destroyAllChildWidget()
205  {
206  WidgetManager& manager = WidgetManager::getInstance();
207  while (!mWidgetChild.empty())
208  {
209  // сразу себя отписывем, иначе вложенной удаление убивает все
210  Widget* widget = mWidgetChild.back();
211  mWidgetChild.pop_back();
212 
213  // отписываем от всех
214  manager.unlinkFromUnlinkers(widget);
215 
216  // и сами удалим, так как его больше в списке нет
218  }
219  }
220 
221  void PointerManager::setDefaultPointer(const std::string& _value)
222  {
223  Update();
224 
225  mDefaultName = _value;
226  setPointer(mDefaultName, nullptr);
227  }
228 
229  void PointerManager::setLayerName(const std::string& _value)
230  {
231  Update();
232 
233  mLayerName = _value;
234  if (LayerManager::getInstance().isExist(_value))
235  LayerManager::getInstance().attachToLayerNode(mLayerName, mMousePointer);
236  }
237 
238  void PointerManager::Update()
239  {
240  if (mMousePointer == nullptr)
241  mMousePointer = static_cast<ImageBox*>(baseCreateWidget(WidgetStyle::Overlapped, ImageBox::getClassTypeName(), mSkinName, IntCoord(), Align::Default, "", ""));
242  }
243 
244  IPointer* PointerManager::getByName(const std::string& _name) const
245  {
246  IResource* result = nullptr;
247  if (!_name.empty() && _name != mXmlDefaultPointerValue)
248  result = ResourceManager::getInstance().getByName(_name, false);
249 
250  if (result == nullptr)
251  result = ResourceManager::getInstance().getByName(mDefaultName, false);
252 
253  return result ? result->castType<IPointer>(false) : nullptr;
254  }
255 
256  void PointerManager::notifyChangeMouseFocus(Widget* _widget)
257  {
258  std::string pointer = (_widget == nullptr || !_widget->getInheritedEnabled()) ? "" : _widget->getPointer();
259  if (pointer != mCurrentMousePointer)
260  {
261  mCurrentMousePointer = pointer;
262  if (mCurrentMousePointer.empty())
263  {
265  eventChangeMousePointer(mDefaultName);
266  }
267  else
268  {
269  setPointer(mCurrentMousePointer, _widget);
270  eventChangeMousePointer(mCurrentMousePointer);
271  }
272  }
273  }
274 
275  void PointerManager::setPointer(const std::string& _name)
276  {
277  setPointer(_name, nullptr);
278  }
279 
281  {
282  return mVisible;
283  }
284 
285  const std::string& PointerManager::getDefaultPointer() const
286  {
287  return mDefaultName;
288  }
289 
290  const std::string& PointerManager::getLayerName() const
291  {
292  return mLayerName;
293  }
294 
295 } // namespace MyGUI