MyGUI  3.2.0
MyGUI_PointerManager.cpp
Go to the documentation of this file.
1 
6 /*
7  This file is part of MyGUI.
8 
9  MyGUI is free software: you can redistribute it and/or modify
10  it under the terms of the GNU Lesser General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  (at your option) any later version.
13 
14  MyGUI is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU Lesser General Public License for more details.
18 
19  You should have received a copy of the GNU Lesser General Public License
20  along with MyGUI. If not, see <http://www.gnu.org/licenses/>.
21 */
22 #include "MyGUI_Precompiled.h"
23 #include "MyGUI_PointerManager.h"
24 #include "MyGUI_ResourceManager.h"
25 #include "MyGUI_LayerManager.h"
26 #include "MyGUI_CoordConverter.h"
27 #include "MyGUI_WidgetManager.h"
28 #include "MyGUI_XmlDocument.h"
29 #include "MyGUI_Widget.h"
30 #include "MyGUI_FactoryManager.h"
31 #include "MyGUI_InputManager.h"
32 #include "MyGUI_Gui.h"
33 
36 
37 namespace MyGUI
38 {
39 
40  const std::string XML_TYPE("Pointer");
41  const std::string XML_TYPE_RESOURCE("Resource");
42  const std::string XML_TYPE_PROPERTY("Property");
43  const std::string RESOURCE_DEFAULT_NAME("Default");
44 
45  template <> PointerManager* Singleton<PointerManager>::msInstance = nullptr;
46  template <> const char* Singleton<PointerManager>::mClassTypeName("PointerManager");
47 
49  mVisible(false),
50  mWidgetOwner(nullptr),
51  mMousePointer(nullptr),
52  mPointer(nullptr),
53  mIsInitialise(false)
54  {
55  }
56 
58  {
59  MYGUI_ASSERT(!mIsInitialise, getClassTypeName() << " initialised twice");
60  MYGUI_LOG(Info, "* Initialise: " << getClassTypeName());
61 
62  Gui::getInstance().eventFrameStart += newDelegate(this, &PointerManager::notifyFrameStart);
63  InputManager::getInstance().eventChangeMouseFocus += newDelegate(this, &PointerManager::notifyChangeMouseFocus);
65 
67 
70 
71  mPointer = nullptr;
72  mMousePointer = nullptr;
73  mWidgetOwner = nullptr;
74  mVisible = true;
75 
76  mSkinName = "ImageBox";
77 
78  MYGUI_LOG(Info, getClassTypeName() << " successfully initialized");
79  mIsInitialise = true;
80  }
81 
83  {
84  MYGUI_ASSERT(mIsInitialise, getClassTypeName() << " is not initialised");
85  MYGUI_LOG(Info, "* Shutdown: " << getClassTypeName());
86 
87  InputManager::getInstance().eventChangeMouseFocus -= newDelegate(this, &PointerManager::notifyChangeMouseFocus);
88  Gui::getInstance().eventFrameStart -= newDelegate(this, &PointerManager::notifyFrameStart);
89 
92 
93  // удаляем все виджеты
94  _destroyAllChildWidget();
95 
96  mWidgetOwner = nullptr;
97 
100 
101  MYGUI_LOG(Info, getClassTypeName() << " successfully shutdown");
102  mIsInitialise = false;
103  }
104 
105  void PointerManager::_load(xml::ElementPtr _node, const std::string& _file, Version _version)
106  {
107  std::string pointer;
108  std::string layer;
109 
111  while (node.next())
112  {
113  if (node->getName() == XML_TYPE)
114  {
115  layer = node->findAttribute("layer");
116  pointer = node->findAttribute("default");
117 
118  // сохраняем
119  std::string shared_text = node->findAttribute("texture");
120 
121  // берем детей и крутимся, основной цикл
123  while (info.next("Info"))
124  {
125  std::string name = info->findAttribute("name");
126  if (name.empty()) continue;
127 
128  std::string texture = info->findAttribute("texture");
129 
130  std::string type = (shared_text.empty() && texture.empty()) ? "ResourceImageSetPointer" : "ResourceManualPointer";
131 
132  xml::Document doc;
133  xml::ElementPtr root = doc.createRoot("MyGUI");
134  xml::ElementPtr newnode = root->createChild("Resource");
135  newnode->addAttribute("type", type);
136  newnode->addAttribute("name", name);
137 
138  std::string tmp;
139  if (info->findAttribute("point", tmp))
140  {
141  xml::ElementPtr prop = newnode->createChild("Property");
142  prop->addAttribute("key", "Point");
143  prop->addAttribute("value", tmp);
144  }
145 
146  if (info->findAttribute("size", tmp))
147  {
148  xml::ElementPtr prop = newnode->createChild("Property");
149  prop->addAttribute("key", "Size");
150  prop->addAttribute("value", tmp);
151  }
152 
153  if (info->findAttribute("resource", tmp))
154  {
155  xml::ElementPtr prop = newnode->createChild("Property");
156  prop->addAttribute("key", "Resource");
157  prop->addAttribute("value", tmp);
158  }
159 
160  if (info->findAttribute("offset", tmp))
161  {
162  xml::ElementPtr prop = newnode->createChild("Property");
163  prop->addAttribute("key", "Coord");
164  prop->addAttribute("value", tmp);
165  }
166 
167  if (!shared_text.empty() || !texture.empty())
168  {
169  xml::ElementPtr prop = newnode->createChild("Property");
170  prop->addAttribute("key", "Texture");
171  prop->addAttribute("value", shared_text.empty() ? texture : shared_text);
172  }
173 
174  ResourceManager::getInstance().loadFromXmlNode(root, _file, _version);
175  }
176 
177  }
178  else if (node->getName() == XML_TYPE_PROPERTY)
179  {
180  const std::string& key = node->findAttribute("key");
181  const std::string& value = node->findAttribute("value");
182  if (key == "Default")
183  setDefaultPointer(value);
184  else if (key == "Layer")
185  setLayerName(value);
186  else if (key == "Skin")
187  mSkinName = value;
188  }
189  }
190 
191  if (!layer.empty())
192  setLayerName(layer);
193 
194  if (!pointer.empty())
195  setDefaultPointer(pointer);
196 
197  }
198 
199  void PointerManager::notifyFrameStart(float _time)
200  {
202  if (nullptr != mMousePointer && mPointer != nullptr)
203  mPointer->setPosition(mMousePointer, mPoint);
204  }
205 
206  void PointerManager::setVisible(bool _visible)
207  {
208  if (nullptr != mMousePointer) mMousePointer->setVisible(_visible);
209  mVisible = _visible;
210  }
211 
212  void PointerManager::setPointer(const std::string& _name, Widget* _owner)
213  {
214  if (nullptr == mMousePointer)
215  return;
216 
217  IResource* result = getByName(_name);
218  if (result == nullptr)
219  {
220  mPointer = nullptr;
221  mMousePointer->setVisible(false);
222  return;
223  }
224 
225  mMousePointer->setVisible(mVisible);
226  mPointer = result->castType<IPointer>();
227  mPointer->setImage(mMousePointer);
228  mPointer->setPosition(mMousePointer, mPoint);
229 
230  mWidgetOwner = _owner;
231  }
232 
233  void PointerManager::_unlinkWidget(Widget* _widget)
234  {
235  if (_widget == mWidgetOwner) setPointer(mDefaultName, nullptr);
236  else if (_widget == mMousePointer) mMousePointer = nullptr;
237  }
238 
240  {
241  setPointer(mDefaultName, nullptr);
242  }
243 
244  // создает виджет
245  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)
246  {
247  Widget* widget = WidgetManager::getInstance().createWidget(_style, _type, _skin, _coord, /*_align, */nullptr, nullptr, /*this, */_name);
248  mWidgetChild.push_back(widget);
249 
250  widget->setAlign(_align);
251 
252  // присоединяем виджет с уровню
253  if (!_layer.empty())
255  return widget;
256  }
257 
258  // удяляет неудачника
259  void PointerManager::_destroyChildWidget(Widget* _widget)
260  {
261  MYGUI_ASSERT(nullptr != _widget, "invalid widget pointer");
262 
263  VectorWidgetPtr::iterator iter = std::find(mWidgetChild.begin(), mWidgetChild.end(), _widget);
264  if (iter != mWidgetChild.end())
265  {
266  // сохраняем указатель
267  MyGUI::Widget* widget = *iter;
268 
269  // удаляем из списка
270  mWidgetChild.erase(iter);
271 
272  // отписываем от всех
274 
275  // непосредственное удаление
277  }
278  else
279  {
280  MYGUI_EXCEPT("Widget '" << _widget->getName() << "' not found");
281  }
282  }
283 
284  // удаляет всех детей
285  void PointerManager::_destroyAllChildWidget()
286  {
287  WidgetManager& manager = WidgetManager::getInstance();
288  while (!mWidgetChild.empty())
289  {
290  // сразу себя отписывем, иначе вложенной удаление убивает все
291  Widget* widget = mWidgetChild.back();
292  mWidgetChild.pop_back();
293 
294  // отписываем от всех
295  manager.unlinkFromUnlinkers(widget);
296 
297  // и сами удалим, так как его больше в списке нет
299  }
300  }
301 
302  void PointerManager::setDefaultPointer(const std::string& _value)
303  {
304  Update();
305 
306  mDefaultName = _value;
307  setPointer(mDefaultName, nullptr);
308  }
309 
310  void PointerManager::setLayerName(const std::string& _value)
311  {
312  Update();
313 
314  mLayerName = _value;
315  if (LayerManager::getInstance().isExist(_value))
316  LayerManager::getInstance().attachToLayerNode(mLayerName, mMousePointer);
317  }
318 
319  void PointerManager::Update()
320  {
321  if (mMousePointer == nullptr)
322  mMousePointer = static_cast<ImageBox*>(baseCreateWidget(WidgetStyle::Overlapped, ImageBox::getClassTypeName(), mSkinName, IntCoord(), Align::Default, "", ""));
323  }
324 
325  IPointer* PointerManager::getByName(const std::string& _name) const
326  {
327  IResource* result = nullptr;
328  if (!_name.empty() && _name != RESOURCE_DEFAULT_NAME)
329  result = ResourceManager::getInstance().getByName(_name, false);
330 
331  if (result == nullptr)
332  result = ResourceManager::getInstance().getByName(mDefaultName, false);
333 
334  return result ? result->castType<IPointer>(false) : nullptr;
335  }
336 
337  void PointerManager::notifyChangeMouseFocus(Widget* _widget)
338  {
339  std::string pointer = (_widget == nullptr || !_widget->getEnabled()) ? "" : _widget->getPointer();
340  if (pointer != mCurrentMousePointer)
341  {
342  mCurrentMousePointer = pointer;
343  if (mCurrentMousePointer.empty())
344  {
346  eventChangeMousePointer(mDefaultName);
347  }
348  else
349  {
350  setPointer(mCurrentMousePointer, _widget);
351  eventChangeMousePointer(mCurrentMousePointer);
352  }
353  }
354  }
355 
356  void PointerManager::setPointer(const std::string& _name)
357  {
358  setPointer(_name, nullptr);
359  }
360 
362  {
363  return mVisible;
364  }
365 
366  const std::string& PointerManager::getDefaultPointer() const
367  {
368  return mDefaultName;
369  }
370 
371  const std::string& PointerManager::getLayerName() const
372  {
373  return mLayerName;
374  }
375 
376 } // namespace MyGUI
const std::string RESOURCE_DEFAULT_NAME("Default")
ElementPtr createRoot(const std::string &_name)
EventHandle_FrameEventDelegate eventFrameStart
Definition: MyGUI_Gui.h:166
static const std::string & getClassTypeName()
void unregisterLoadXmlDelegate(const std::string &_key)
LoadXmlDelegate & registerLoadXmlDelegate(const std::string &_key)
Element * ElementPtr
delegates::IDelegate0 * newDelegate(void(*_func)())
static Gui & getInstance()
void loadFromXmlNode(xml::ElementPtr _node, const std::string &_file, Version _version)
bool findAttribute(const std::string &_name, std::string &_value)
void setVisible(bool _visible)
virtual void setVisible(bool _value)
static const char * getClassTypeName()
delegates::CMultiDelegate1< const std::string & > eventChangeMousePointer
const std::string & getLayerName() const
#define nullptr
const std::string XML_TYPE("Font")
void unlinkFromUnlinkers(Widget *_widget)
types::TCoord< int > IntCoord
Definition: MyGUI_Types.h:50
IResource * getByName(const std::string &_name, bool _throw=true) const
#define MYGUI_LOG(level, text)
#define MYGUI_EXCEPT(dest)
void setDefaultPointer(const std::string &_value)
virtual void setImage(ImageBox *_image)=0
const std::string & getDefaultPointer() const
#define MYGUI_ASSERT(exp, dest)
const std::string XML_TYPE_PROPERTY("Property")
void attachToLayerNode(const std::string &_name, Widget *_item)
bool getEnabled() const
void _deleteWidget(Widget *_widget)
Type * castType(bool _throw=true)
Definition: MyGUI_IObject.h:33
void registerUnlinker(IUnlinkWidget *_unlink)
void setPointer(const std::string &_name)
void unregisterFactory(const std::string &_category, const std::string &_type)
Widget * createWidget(WidgetStyle _style, const std::string &_type, const std::string &_skin, const IntCoord &_coord, Widget *_parent, ICroppedRectangle *_cropeedParent, const std::string &_name)
virtual void setAlign(Align _value)
void registerFactory(const std::string &_category, const std::string &_type, Delegate::IDelegate *_delegate)
ElementEnumerator getElementEnumerator()
virtual void setPosition(ImageBox *_image, const IntPoint &_point)=0
const std::string & getPointer() const
const std::string & getName() const
const IntPoint & getMousePosition() const
void addAttribute(const std::string &_key, const T &_value)
IPointer * getByName(const std::string &_name) const
const std::string XML_TYPE_RESOURCE("Resource")
void setLayerName(const std::string &_value)
ElementPtr createChild(const std::string &_name, const std::string &_content="", ElementType _type=ElementType::Normal)
void unregisterUnlinker(IUnlinkWidget *_unlink)
delegates::CMultiDelegate1< Widget * > eventChangeMouseFocus