MyGUI 3.0.1

MyGUI_PointerManager.cpp

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