MyGUI  3.2.0
MyGUI_LayerManager.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_LayerManager.h"
00024 #include "MyGUI_LayerItem.h"
00025 #include "MyGUI_WidgetManager.h"
00026 #include "MyGUI_RenderManager.h"
00027 #include "MyGUI_Widget.h"
00028 #include "MyGUI_FactoryManager.h"
00029 
00030 #include "MyGUI_SharedLayer.h"
00031 #include "MyGUI_OverlappedLayer.h"
00032 
00033 namespace MyGUI
00034 {
00035 
00036     const std::string XML_TYPE("Layer");
00037 
00038     template <> LayerManager* Singleton<LayerManager>::msInstance = nullptr;
00039     template <> const char* Singleton<LayerManager>::mClassTypeName("LayerManager");
00040 
00041     LayerManager::LayerManager() :
00042         mIsInitialise(false)
00043     {
00044     }
00045 
00046     void LayerManager::initialise()
00047     {
00048         MYGUI_ASSERT(!mIsInitialise, getClassTypeName() << " initialised twice");
00049         MYGUI_LOG(Info, "* Initialise: " << getClassTypeName());
00050 
00051         WidgetManager::getInstance().registerUnlinker(this);
00052         ResourceManager::getInstance().registerLoadXmlDelegate(XML_TYPE) = newDelegate(this, &LayerManager::_load);
00053 
00054         FactoryManager::getInstance().registerFactory<SharedLayer>(XML_TYPE);
00055         FactoryManager::getInstance().registerFactory<OverlappedLayer>(XML_TYPE);
00056 
00057         MYGUI_LOG(Info, getClassTypeName() << " successfully initialized");
00058         mIsInitialise = true;
00059     }
00060 
00061     void LayerManager::shutdown()
00062     {
00063         MYGUI_ASSERT(mIsInitialise, getClassTypeName() << " is not initialised");
00064         MYGUI_LOG(Info, "* Shutdown: " << getClassTypeName());
00065 
00066         FactoryManager::getInstance().unregisterFactory<SharedLayer>(XML_TYPE);
00067         FactoryManager::getInstance().unregisterFactory<OverlappedLayer>(XML_TYPE);
00068 
00069         // удаляем все хранители слоев
00070         clear();
00071 
00072         WidgetManager::getInstance().unregisterUnlinker(this);
00073         ResourceManager::getInstance().unregisterLoadXmlDelegate(XML_TYPE);
00074 
00075         MYGUI_LOG(Info, getClassTypeName() << " successfully shutdown");
00076         mIsInitialise = false;
00077     }
00078 
00079     void LayerManager::clear()
00080     {
00081         for (VectorLayer::iterator iter = mLayerNodes.begin(); iter != mLayerNodes.end(); ++iter)
00082         {
00083             destroy(*iter);
00084         }
00085         mLayerNodes.clear();
00086     }
00087 
00088     void LayerManager::_load(xml::ElementPtr _node, const std::string& _file, Version _version)
00089     {
00090         VectorLayer layers;
00091         // берем детей и крутимся, основной цикл
00092         xml::ElementEnumerator layer = _node->getElementEnumerator();
00093         while (layer.next(XML_TYPE))
00094         {
00095 
00096             std::string name;
00097 
00098             if ( !layer->findAttribute("name", name))
00099             {
00100                 MYGUI_LOG(Warning, "Attribute 'name' not found (file : " << _file << ")");
00101                 continue;
00102             }
00103 
00104             for (VectorLayer::iterator iter = layers.begin(); iter != layers.end(); ++iter)
00105             {
00106                 MYGUI_ASSERT((*iter)->getName() != name, "Layer '" << name << "' already exist (file : " << _file << ")");
00107             }
00108 
00109             std::string type = layer->findAttribute("type");
00110             if (type.empty() && _version <= Version(1, 0))
00111             {
00112                 bool overlapped = utility::parseBool(layer->findAttribute("overlapped"));
00113                 type = overlapped ? "OverlappedLayer" : "SharedLayer";
00114             }
00115 
00116             IObject* object = FactoryManager::getInstance().createObject(XML_TYPE, type);
00117             MYGUI_ASSERT(object != nullptr, "factory '" << type << "' is not found");
00118 
00119             ILayer* item = object->castType<ILayer>();
00120             item->deserialization(layer.current(), _version);
00121 
00122             layers.push_back(item);
00123         }
00124 
00125         // теперь мержим новые и старые слои
00126         merge(layers);
00127     }
00128 
00129     void LayerManager::_unlinkWidget(Widget* _widget)
00130     {
00131         detachFromLayer(_widget);
00132     }
00133 
00134     // поправить на виджет и проверять на рутовость
00135     void LayerManager::attachToLayerNode(const std::string& _name, Widget* _item)
00136     {
00137         MYGUI_ASSERT(nullptr != _item, "pointer must be valid");
00138         MYGUI_ASSERT(_item->isRootWidget(), "attached widget must be root");
00139 
00140         // сначала отсоединяем
00141         _item->detachFromLayer();
00142 
00143         // а теперь аттачим
00144         for (VectorLayer::iterator iter = mLayerNodes.begin(); iter != mLayerNodes.end(); ++iter)
00145         {
00146             if (_name == (*iter)->getName())
00147             {
00148                 ILayerNode* node = (*iter)->createChildItemNode();
00149                 node->attachLayerItem(_item);
00150 
00151                 return;
00152             }
00153         }
00154         MYGUI_LOG(Error, "Layer '" << _name << "' is not found");
00155         //MYGUI_EXCEPT("Layer '" << _name << "' is not found");
00156     }
00157 
00158     void LayerManager::detachFromLayer(Widget* _item)
00159     {
00160         MYGUI_ASSERT(nullptr != _item, "pointer must be valid");
00161         _item->detachFromLayer();
00162     }
00163 
00164     void LayerManager::upLayerItem(Widget* _item)
00165     {
00166         MYGUI_ASSERT(nullptr != _item, "pointer must be valid");
00167         _item->upLayerItem();
00168     }
00169 
00170     bool LayerManager::isExist(const std::string& _name) const
00171     {
00172         return getByName(_name, false) != nullptr;
00173     }
00174 
00175     void LayerManager::merge(VectorLayer& _layers)
00176     {
00177         for (VectorLayer::iterator iter = mLayerNodes.begin(); iter != mLayerNodes.end(); ++iter)
00178         {
00179             if ((*iter) == nullptr) continue;
00180             bool find = false;
00181             std::string name = (*iter)->getName();
00182             for (VectorLayer::iterator iter2 = _layers.begin(); iter2 != _layers.end(); ++iter2)
00183             {
00184                 if (name == (*iter2)->getName())
00185                 {
00186                     // заменяем новый слой, на уже существующий
00187                     delete (*iter2);
00188                     (*iter2) = (*iter);
00189                     (*iter) = nullptr;
00190                     find = true;
00191                     break;
00192                 }
00193             }
00194             if (!find)
00195             {
00196                 destroy(*iter);
00197                 (*iter) = nullptr;
00198             }
00199         }
00200 
00201         // теперь в основной
00202         mLayerNodes = _layers;
00203     }
00204 
00205     void LayerManager::destroy(ILayer* _layer)
00206     {
00207         MYGUI_LOG(Info, "destroy layer '" << _layer->getName() << "'");
00208         delete _layer;
00209     }
00210     Widget* LayerManager::getWidgetFromPoint(int _left, int _top)
00211     {
00212         VectorLayer::reverse_iterator iter = mLayerNodes.rbegin();
00213         while (iter != mLayerNodes.rend())
00214         {
00215             ILayerItem* item = (*iter)->getLayerItemByPoint(_left, _top);
00216             if (item != nullptr) return static_cast<Widget*>(item);
00217             ++iter;
00218         }
00219         return nullptr;
00220     }
00221 
00222     void LayerManager::renderToTarget(IRenderTarget* _target, bool _update)
00223     {
00224         for (VectorLayer::iterator iter = mLayerNodes.begin(); iter != mLayerNodes.end(); ++iter)
00225         {
00226             (*iter)->renderToTarget(_target, _update);
00227         }
00228     }
00229 
00230     ILayer* LayerManager::getByName(const std::string& _name, bool _throw) const
00231     {
00232         for (VectorLayer::const_iterator iter = mLayerNodes.begin(); iter != mLayerNodes.end(); ++iter)
00233         {
00234             if (_name == (*iter)->getName())
00235                 return (*iter);
00236         }
00237         MYGUI_ASSERT(!_throw, "Layer '" << _name << "' not found");
00238         return nullptr;
00239     }
00240 
00241     LayerManager::EnumeratorLayer LayerManager::getEnumerator() const
00242     {
00243         return EnumeratorLayer(mLayerNodes);
00244     }
00245 
00246     void LayerManager::resizeView(const IntSize& _viewSize)
00247     {
00248         for (VectorLayer::const_iterator iter = mLayerNodes.begin(); iter != mLayerNodes.end(); ++iter)
00249             (*iter)->resizeView(_viewSize);
00250     }
00251 
00252 } // namespace MyGUI