MyGUI  3.2.1
MyGUI_PointerManager.cpp
Go to the documentation of this file.
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_PointerManager.h"
00009 #include "MyGUI_ResourceManager.h"
00010 #include "MyGUI_LayerManager.h"
00011 #include "MyGUI_CoordConverter.h"
00012 #include "MyGUI_WidgetManager.h"
00013 #include "MyGUI_XmlDocument.h"
00014 #include "MyGUI_Widget.h"
00015 #include "MyGUI_FactoryManager.h"
00016 #include "MyGUI_InputManager.h"
00017 #include "MyGUI_Gui.h"
00018 
00019 #include "MyGUI_ResourceManualPointer.h"
00020 #include "MyGUI_ResourceImageSetPointer.h"
00021 
00022 namespace MyGUI
00023 {
00024 
00025     template <> PointerManager* Singleton<PointerManager>::msInstance = nullptr;
00026     template <> const char* Singleton<PointerManager>::mClassTypeName = "PointerManager";
00027 
00028     PointerManager::PointerManager() :
00029         mVisible(false),
00030         mWidgetOwner(nullptr),
00031         mMousePointer(nullptr),
00032         mPointer(nullptr),
00033         mIsInitialise(false),
00034         mXmlPointerTagName("Pointer"),
00035         mXmlPropertyTagName("Property"),
00036         mXmlDefaultPointerValue("Default")
00037     {
00038     }
00039 
00040     void PointerManager::initialise()
00041     {
00042         MYGUI_ASSERT(!mIsInitialise, getClassTypeName() << " initialised twice");
00043         MYGUI_LOG(Info, "* Initialise: " << getClassTypeName());
00044 
00045         Gui::getInstance().eventFrameStart += newDelegate(this, &PointerManager::notifyFrameStart);
00046         InputManager::getInstance().eventChangeMouseFocus += newDelegate(this, &PointerManager::notifyChangeMouseFocus);
00047         WidgetManager::getInstance().registerUnlinker(this);
00048 
00049         ResourceManager::getInstance().registerLoadXmlDelegate(mXmlPointerTagName) = newDelegate(this, &PointerManager::_load);
00050 
00051         std::string resourceCategory = ResourceManager::getInstance().getCategoryName();
00052         FactoryManager::getInstance().registerFactory<ResourceManualPointer>(resourceCategory);
00053         FactoryManager::getInstance().registerFactory<ResourceImageSetPointer>(resourceCategory);
00054 
00055         mPointer = nullptr;
00056         mMousePointer = nullptr;
00057         mWidgetOwner = nullptr;
00058         mVisible = true;
00059 
00060         mSkinName = "ImageBox";
00061 
00062         MYGUI_LOG(Info, getClassTypeName() << " successfully initialized");
00063         mIsInitialise = true;
00064     }
00065 
00066     void PointerManager::shutdown()
00067     {
00068         MYGUI_ASSERT(mIsInitialise, getClassTypeName() << " is not initialised");
00069         MYGUI_LOG(Info, "* Shutdown: " << getClassTypeName());
00070 
00071         InputManager::getInstance().eventChangeMouseFocus -= newDelegate(this, &PointerManager::notifyChangeMouseFocus);
00072         Gui::getInstance().eventFrameStart -= newDelegate(this, &PointerManager::notifyFrameStart);
00073 
00074         std::string resourceCategory = ResourceManager::getInstance().getCategoryName();
00075         FactoryManager::getInstance().unregisterFactory<ResourceManualPointer>(resourceCategory);
00076         FactoryManager::getInstance().unregisterFactory<ResourceImageSetPointer>(resourceCategory);
00077 
00078         // удаляем все виджеты
00079         _destroyAllChildWidget();
00080 
00081         mWidgetOwner = nullptr;
00082 
00083         WidgetManager::getInstance().unregisterUnlinker(this);
00084         ResourceManager::getInstance().unregisterLoadXmlDelegate(mXmlPointerTagName);
00085 
00086         MYGUI_LOG(Info, getClassTypeName() << " successfully shutdown");
00087         mIsInitialise = false;
00088     }
00089 
00090     void PointerManager::_load(xml::ElementPtr _node, const std::string& _file, Version _version)
00091     {
00092 #ifndef MYGUI_DONT_USE_OBSOLETE
00093         loadOldPointerFormat(_node, _file, _version, mXmlPointerTagName);
00094 #endif // MYGUI_DONT_USE_OBSOLETE
00095 
00096         xml::ElementEnumerator node = _node->getElementEnumerator();
00097         while (node.next())
00098         {
00099             if (node->getName() == mXmlPropertyTagName)
00100             {
00101                 const std::string& key = node->findAttribute("key");
00102                 const std::string& value = node->findAttribute("value");
00103                 if (key == "Default")
00104                     setDefaultPointer(value);
00105                 else if (key == "Layer")
00106                     setLayerName(value);
00107                 else if (key == "Skin")
00108                     mSkinName = value;
00109             }
00110         }
00111     }
00112 
00113     void PointerManager::notifyFrameStart(float _time)
00114     {
00115         mPoint = InputManager::getInstance().getMousePosition();
00116         if (mOldPoint != mPoint)
00117         {
00118             mOldPoint = mPoint;
00119 
00120             if (nullptr != mMousePointer && mPointer != nullptr)
00121                 mPointer->setPosition(mMousePointer, mPoint);
00122         }
00123     }
00124 
00125     void PointerManager::setVisible(bool _visible)
00126     {
00127         if (nullptr != mMousePointer) mMousePointer->setVisible(_visible);
00128         mVisible = _visible;
00129     }
00130 
00131     void PointerManager::setPointer(const std::string& _name, Widget* _owner)
00132     {
00133         if (nullptr == mMousePointer)
00134             return;
00135 
00136         IResource* result = getByName(_name);
00137         if (result == nullptr)
00138         {
00139             mPointer = nullptr;
00140             mMousePointer->setVisible(false);
00141             return;
00142         }
00143 
00144         mMousePointer->setVisible(mVisible);
00145         mPointer = result->castType<IPointer>();
00146         mPointer->setImage(mMousePointer);
00147         mPointer->setPosition(mMousePointer, mPoint);
00148 
00149         mWidgetOwner = _owner;
00150     }
00151 
00152     void PointerManager::_unlinkWidget(Widget* _widget)
00153     {
00154         if (_widget == mWidgetOwner) setPointer(mDefaultName, nullptr);
00155         else if (_widget == mMousePointer) mMousePointer = nullptr;
00156     }
00157 
00158     void PointerManager::resetToDefaultPointer()
00159     {
00160         setPointer(mDefaultName, nullptr);
00161     }
00162 
00163     // создает виджет
00164     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)
00165     {
00166         Widget* widget = WidgetManager::getInstance().createWidget(_style, _type, _skin, _coord, /*_align, */nullptr, nullptr, /*this, */_name);
00167         mWidgetChild.push_back(widget);
00168 
00169         widget->setAlign(_align);
00170 
00171         // присоединяем виджет с уровню
00172         if (!_layer.empty())
00173             LayerManager::getInstance().attachToLayerNode(_layer, widget);
00174         return widget;
00175     }
00176 
00177     // удяляет неудачника
00178     void PointerManager::_destroyChildWidget(Widget* _widget)
00179     {
00180         MYGUI_ASSERT(nullptr != _widget, "invalid widget pointer");
00181 
00182         VectorWidgetPtr::iterator iter = std::find(mWidgetChild.begin(), mWidgetChild.end(), _widget);
00183         if (iter != mWidgetChild.end())
00184         {
00185             // сохраняем указатель
00186             MyGUI::Widget* widget = *iter;
00187 
00188             // удаляем из списка
00189             mWidgetChild.erase(iter);
00190 
00191             // отписываем от всех
00192             WidgetManager::getInstance().unlinkFromUnlinkers(_widget);
00193 
00194             // непосредственное удаление
00195             WidgetManager::getInstance()._deleteWidget(widget);
00196         }
00197         else
00198         {
00199             MYGUI_EXCEPT("Widget '" << _widget->getName() << "' not found");
00200         }
00201     }
00202 
00203     // удаляет всех детей
00204     void PointerManager::_destroyAllChildWidget()
00205     {
00206         WidgetManager& manager = WidgetManager::getInstance();
00207         while (!mWidgetChild.empty())
00208         {
00209             // сразу себя отписывем, иначе вложенной удаление убивает все
00210             Widget* widget = mWidgetChild.back();
00211             mWidgetChild.pop_back();
00212 
00213             // отписываем от всех
00214             manager.unlinkFromUnlinkers(widget);
00215 
00216             // и сами удалим, так как его больше в списке нет
00217             WidgetManager::getInstance()._deleteWidget(widget);
00218         }
00219     }
00220 
00221     void PointerManager::setDefaultPointer(const std::string& _value)
00222     {
00223         Update();
00224 
00225         mDefaultName = _value;
00226         setPointer(mDefaultName, nullptr);
00227     }
00228 
00229     void PointerManager::setLayerName(const std::string& _value)
00230     {
00231         Update();
00232 
00233         mLayerName = _value;
00234         if (LayerManager::getInstance().isExist(_value))
00235             LayerManager::getInstance().attachToLayerNode(mLayerName, mMousePointer);
00236     }
00237 
00238     void PointerManager::Update()
00239     {
00240         if (mMousePointer == nullptr)
00241             mMousePointer = static_cast<ImageBox*>(baseCreateWidget(WidgetStyle::Overlapped, ImageBox::getClassTypeName(), mSkinName, IntCoord(), Align::Default, "", ""));
00242     }
00243 
00244     IPointer* PointerManager::getByName(const std::string& _name) const
00245     {
00246         IResource* result = nullptr;
00247         if (!_name.empty() && _name != mXmlDefaultPointerValue)
00248             result = ResourceManager::getInstance().getByName(_name, false);
00249 
00250         if (result == nullptr)
00251             result = ResourceManager::getInstance().getByName(mDefaultName, false);
00252 
00253         return result ? result->castType<IPointer>(false) : nullptr;
00254     }
00255 
00256     void PointerManager::notifyChangeMouseFocus(Widget* _widget)
00257     {
00258         std::string pointer = (_widget == nullptr || !_widget->getInheritedEnabled()) ? "" : _widget->getPointer();
00259         if (pointer != mCurrentMousePointer)
00260         {
00261             mCurrentMousePointer = pointer;
00262             if (mCurrentMousePointer.empty())
00263             {
00264                 resetToDefaultPointer();
00265                 eventChangeMousePointer(mDefaultName);
00266             }
00267             else
00268             {
00269                 setPointer(mCurrentMousePointer, _widget);
00270                 eventChangeMousePointer(mCurrentMousePointer);
00271             }
00272         }
00273     }
00274 
00275     void PointerManager::setPointer(const std::string& _name)
00276     {
00277         setPointer(_name, nullptr);
00278     }
00279 
00280     bool PointerManager::isVisible() const
00281     {
00282         return mVisible;
00283     }
00284 
00285     const std::string& PointerManager::getDefaultPointer() const
00286     {
00287         return mDefaultName;
00288     }
00289 
00290     const std::string& PointerManager::getLayerName() const
00291     {
00292         return mLayerName;
00293     }
00294 
00295 } // namespace MyGUI