MyGUI  3.2.0
MyGUI_PointerManager.cpp
Go to the documentation of this file.
00001 
00006 /*
00007     This file is part of MyGUI.
00008 
00009     MyGUI is free software: you can redistribute it and/or modify
00010     it under the terms of the GNU Lesser General Public License as published by
00011     the Free Software Foundation, either version 3 of the License, or
00012     (at your option) any later version.
00013 
00014     MyGUI is distributed in the hope that it will be useful,
00015     but WITHOUT ANY WARRANTY; without even the implied warranty of
00016     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017     GNU Lesser General Public License for more details.
00018 
00019     You should have received a copy of the GNU Lesser General Public License
00020     along with MyGUI.  If not, see <http://www.gnu.org/licenses/>.
00021 */
00022 #include "MyGUI_Precompiled.h"
00023 #include "MyGUI_PointerManager.h"
00024 #include "MyGUI_ResourceManager.h"
00025 #include "MyGUI_LayerManager.h"
00026 #include "MyGUI_CoordConverter.h"
00027 #include "MyGUI_WidgetManager.h"
00028 #include "MyGUI_XmlDocument.h"
00029 #include "MyGUI_Widget.h"
00030 #include "MyGUI_FactoryManager.h"
00031 #include "MyGUI_InputManager.h"
00032 #include "MyGUI_Gui.h"
00033 
00034 #include "MyGUI_ResourceManualPointer.h"
00035 #include "MyGUI_ResourceImageSetPointer.h"
00036 
00037 namespace MyGUI
00038 {
00039 
00040     const std::string XML_TYPE("Pointer");
00041     const std::string XML_TYPE_RESOURCE("Resource");
00042     const std::string XML_TYPE_PROPERTY("Property");
00043     const std::string RESOURCE_DEFAULT_NAME("Default");
00044 
00045     template <> PointerManager* Singleton<PointerManager>::msInstance = nullptr;
00046     template <> const char* Singleton<PointerManager>::mClassTypeName("PointerManager");
00047 
00048     PointerManager::PointerManager() :
00049         mVisible(false),
00050         mWidgetOwner(nullptr),
00051         mMousePointer(nullptr),
00052         mPointer(nullptr),
00053         mIsInitialise(false)
00054     {
00055     }
00056 
00057     void PointerManager::initialise()
00058     {
00059         MYGUI_ASSERT(!mIsInitialise, getClassTypeName() << " initialised twice");
00060         MYGUI_LOG(Info, "* Initialise: " << getClassTypeName());
00061 
00062         Gui::getInstance().eventFrameStart += newDelegate(this, &PointerManager::notifyFrameStart);
00063         InputManager::getInstance().eventChangeMouseFocus += newDelegate(this, &PointerManager::notifyChangeMouseFocus);
00064         WidgetManager::getInstance().registerUnlinker(this);
00065 
00066         ResourceManager::getInstance().registerLoadXmlDelegate(XML_TYPE) = newDelegate(this, &PointerManager::_load);
00067 
00068         FactoryManager::getInstance().registerFactory<ResourceManualPointer>(XML_TYPE_RESOURCE);
00069         FactoryManager::getInstance().registerFactory<ResourceImageSetPointer>(XML_TYPE_RESOURCE);
00070 
00071         mPointer = nullptr;
00072         mMousePointer = nullptr;
00073         mWidgetOwner = nullptr;
00074         mVisible = true;
00075 
00076         mSkinName = "ImageBox";
00077 
00078         MYGUI_LOG(Info, getClassTypeName() << " successfully initialized");
00079         mIsInitialise = true;
00080     }
00081 
00082     void PointerManager::shutdown()
00083     {
00084         MYGUI_ASSERT(mIsInitialise, getClassTypeName() << " is not initialised");
00085         MYGUI_LOG(Info, "* Shutdown: " << getClassTypeName());
00086 
00087         InputManager::getInstance().eventChangeMouseFocus -= newDelegate(this, &PointerManager::notifyChangeMouseFocus);
00088         Gui::getInstance().eventFrameStart -= newDelegate(this, &PointerManager::notifyFrameStart);
00089 
00090         FactoryManager::getInstance().unregisterFactory<ResourceManualPointer>(XML_TYPE_RESOURCE);
00091         FactoryManager::getInstance().unregisterFactory<ResourceImageSetPointer>(XML_TYPE_RESOURCE);
00092 
00093         // удаляем все виджеты
00094         _destroyAllChildWidget();
00095 
00096         mWidgetOwner = nullptr;
00097 
00098         WidgetManager::getInstance().unregisterUnlinker(this);
00099         ResourceManager::getInstance().unregisterLoadXmlDelegate(XML_TYPE);
00100 
00101         MYGUI_LOG(Info, getClassTypeName() << " successfully shutdown");
00102         mIsInitialise = false;
00103     }
00104 
00105     void PointerManager::_load(xml::ElementPtr _node, const std::string& _file, Version _version)
00106     {
00107         std::string pointer;
00108         std::string layer;
00109 
00110         xml::ElementEnumerator node = _node->getElementEnumerator();
00111         while (node.next())
00112         {
00113             if (node->getName() == XML_TYPE)
00114             {
00115                 layer = node->findAttribute("layer");
00116                 pointer = node->findAttribute("default");
00117 
00118                 // сохраняем
00119                 std::string shared_text = node->findAttribute("texture");
00120 
00121                 // берем детей и крутимся, основной цикл
00122                 xml::ElementEnumerator info = node->getElementEnumerator();
00123                 while (info.next("Info"))
00124                 {
00125                     std::string name = info->findAttribute("name");
00126                     if (name.empty()) continue;
00127 
00128                     std::string texture = info->findAttribute("texture");
00129 
00130                     std::string type = (shared_text.empty() && texture.empty()) ? "ResourceImageSetPointer" : "ResourceManualPointer";
00131 
00132                     xml::Document doc;
00133                     xml::ElementPtr root = doc.createRoot("MyGUI");
00134                     xml::ElementPtr newnode = root->createChild("Resource");
00135                     newnode->addAttribute("type", type);
00136                     newnode->addAttribute("name", name);
00137 
00138                     std::string tmp;
00139                     if (info->findAttribute("point", tmp))
00140                     {
00141                         xml::ElementPtr prop = newnode->createChild("Property");
00142                         prop->addAttribute("key", "Point");
00143                         prop->addAttribute("value", tmp);
00144                     }
00145 
00146                     if (info->findAttribute("size", tmp))
00147                     {
00148                         xml::ElementPtr prop = newnode->createChild("Property");
00149                         prop->addAttribute("key", "Size");
00150                         prop->addAttribute("value", tmp);
00151                     }
00152 
00153                     if (info->findAttribute("resource", tmp))
00154                     {
00155                         xml::ElementPtr prop = newnode->createChild("Property");
00156                         prop->addAttribute("key", "Resource");
00157                         prop->addAttribute("value", tmp);
00158                     }
00159 
00160                     if (info->findAttribute("offset", tmp))
00161                     {
00162                         xml::ElementPtr prop = newnode->createChild("Property");
00163                         prop->addAttribute("key", "Coord");
00164                         prop->addAttribute("value", tmp);
00165                     }
00166 
00167                     if (!shared_text.empty() || !texture.empty())
00168                     {
00169                         xml::ElementPtr prop = newnode->createChild("Property");
00170                         prop->addAttribute("key", "Texture");
00171                         prop->addAttribute("value",  shared_text.empty() ? texture : shared_text);
00172                     }
00173 
00174                     ResourceManager::getInstance().loadFromXmlNode(root, _file, _version);
00175                 }
00176 
00177             }
00178             else if (node->getName() == XML_TYPE_PROPERTY)
00179             {
00180                 const std::string& key = node->findAttribute("key");
00181                 const std::string& value = node->findAttribute("value");
00182                 if (key == "Default")
00183                     setDefaultPointer(value);
00184                 else if (key == "Layer")
00185                     setLayerName(value);
00186                 else if (key == "Skin")
00187                     mSkinName = value;
00188             }
00189         }
00190 
00191         if (!layer.empty())
00192             setLayerName(layer);
00193 
00194         if (!pointer.empty())
00195             setDefaultPointer(pointer);
00196 
00197     }
00198 
00199     void PointerManager::notifyFrameStart(float _time)
00200     {
00201         mPoint = InputManager::getInstance().getMousePosition();
00202         if (nullptr != mMousePointer && mPointer != nullptr)
00203             mPointer->setPosition(mMousePointer, mPoint);
00204     }
00205 
00206     void PointerManager::setVisible(bool _visible)
00207     {
00208         if (nullptr != mMousePointer) mMousePointer->setVisible(_visible);
00209         mVisible = _visible;
00210     }
00211 
00212     void PointerManager::setPointer(const std::string& _name, Widget* _owner)
00213     {
00214         if (nullptr == mMousePointer)
00215             return;
00216 
00217         IResource* result = getByName(_name);
00218         if (result == nullptr)
00219         {
00220             mPointer = nullptr;
00221             mMousePointer->setVisible(false);
00222             return;
00223         }
00224 
00225         mMousePointer->setVisible(mVisible);
00226         mPointer = result->castType<IPointer>();
00227         mPointer->setImage(mMousePointer);
00228         mPointer->setPosition(mMousePointer, mPoint);
00229 
00230         mWidgetOwner = _owner;
00231     }
00232 
00233     void PointerManager::_unlinkWidget(Widget* _widget)
00234     {
00235         if (_widget == mWidgetOwner) setPointer(mDefaultName, nullptr);
00236         else if (_widget == mMousePointer) mMousePointer = nullptr;
00237     }
00238 
00239     void PointerManager::resetToDefaultPointer()
00240     {
00241         setPointer(mDefaultName, nullptr);
00242     }
00243 
00244     // создает виджет
00245     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)
00246     {
00247         Widget* widget = WidgetManager::getInstance().createWidget(_style, _type, _skin, _coord, /*_align, */nullptr, nullptr, /*this, */_name);
00248         mWidgetChild.push_back(widget);
00249 
00250         widget->setAlign(_align);
00251 
00252         // присоединяем виджет с уровню
00253         if (!_layer.empty())
00254             LayerManager::getInstance().attachToLayerNode(_layer, widget);
00255         return widget;
00256     }
00257 
00258     // удяляет неудачника
00259     void PointerManager::_destroyChildWidget(Widget* _widget)
00260     {
00261         MYGUI_ASSERT(nullptr != _widget, "invalid widget pointer");
00262 
00263         VectorWidgetPtr::iterator iter = std::find(mWidgetChild.begin(), mWidgetChild.end(), _widget);
00264         if (iter != mWidgetChild.end())
00265         {
00266             // сохраняем указатель
00267             MyGUI::Widget* widget = *iter;
00268 
00269             // удаляем из списка
00270             mWidgetChild.erase(iter);
00271 
00272             // отписываем от всех
00273             WidgetManager::getInstance().unlinkFromUnlinkers(_widget);
00274 
00275             // непосредственное удаление
00276             WidgetManager::getInstance()._deleteWidget(widget);
00277         }
00278         else
00279         {
00280             MYGUI_EXCEPT("Widget '" << _widget->getName() << "' not found");
00281         }
00282     }
00283 
00284     // удаляет всех детей
00285     void PointerManager::_destroyAllChildWidget()
00286     {
00287         WidgetManager& manager = WidgetManager::getInstance();
00288         while (!mWidgetChild.empty())
00289         {
00290             // сразу себя отписывем, иначе вложенной удаление убивает все
00291             Widget* widget = mWidgetChild.back();
00292             mWidgetChild.pop_back();
00293 
00294             // отписываем от всех
00295             manager.unlinkFromUnlinkers(widget);
00296 
00297             // и сами удалим, так как его больше в списке нет
00298             WidgetManager::getInstance()._deleteWidget(widget);
00299         }
00300     }
00301 
00302     void PointerManager::setDefaultPointer(const std::string& _value)
00303     {
00304         Update();
00305 
00306         mDefaultName = _value;
00307         setPointer(mDefaultName, nullptr);
00308     }
00309 
00310     void PointerManager::setLayerName(const std::string& _value)
00311     {
00312         Update();
00313 
00314         mLayerName = _value;
00315         if (LayerManager::getInstance().isExist(_value))
00316             LayerManager::getInstance().attachToLayerNode(mLayerName, mMousePointer);
00317     }
00318 
00319     void PointerManager::Update()
00320     {
00321         if (mMousePointer == nullptr)
00322             mMousePointer = static_cast<ImageBox*>(baseCreateWidget(WidgetStyle::Overlapped, ImageBox::getClassTypeName(), mSkinName, IntCoord(), Align::Default, "", ""));
00323     }
00324 
00325     IPointer* PointerManager::getByName(const std::string& _name) const
00326     {
00327         IResource* result = nullptr;
00328         if (!_name.empty() && _name != RESOURCE_DEFAULT_NAME)
00329             result = ResourceManager::getInstance().getByName(_name, false);
00330 
00331         if (result == nullptr)
00332             result = ResourceManager::getInstance().getByName(mDefaultName, false);
00333 
00334         return result ? result->castType<IPointer>(false) : nullptr;
00335     }
00336 
00337     void PointerManager::notifyChangeMouseFocus(Widget* _widget)
00338     {
00339         std::string pointer = (_widget == nullptr || !_widget->getEnabled()) ? "" : _widget->getPointer();
00340         if (pointer != mCurrentMousePointer)
00341         {
00342             mCurrentMousePointer = pointer;
00343             if (mCurrentMousePointer.empty())
00344             {
00345                 resetToDefaultPointer();
00346                 eventChangeMousePointer(mDefaultName);
00347             }
00348             else
00349             {
00350                 setPointer(mCurrentMousePointer, _widget);
00351                 eventChangeMousePointer(mCurrentMousePointer);
00352             }
00353         }
00354     }
00355 
00356     void PointerManager::setPointer(const std::string& _name)
00357     {
00358         setPointer(_name, nullptr);
00359     }
00360 
00361     bool PointerManager::isVisible() const
00362     {
00363         return mVisible;
00364     }
00365 
00366     const std::string& PointerManager::getDefaultPointer() const
00367     {
00368         return mDefaultName;
00369     }
00370 
00371     const std::string& PointerManager::getLayerName() const
00372     {
00373         return mLayerName;
00374     }
00375 
00376 } // namespace MyGUI