MyGUI  3.0.3
MyGUI_LayoutManager.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_LayoutManager.h"
00026 #include "MyGUI_SkinManager.h"
00027 #include "MyGUI_WidgetManager.h"
00028 #include "MyGUI_Widget.h"
00029 #include "MyGUI_CoordConverter.h"
00030 #include "MyGUI_ControllerManager.h"
00031 
00032 namespace MyGUI
00033 {
00034 
00035     const std::string XML_TYPE("Layout");
00036 
00037     MYGUI_INSTANCE_IMPLEMENT( LayoutManager )
00038 
00039     void LayoutManager::initialise()
00040     {
00041         MYGUI_ASSERT(!mIsInitialise, INSTANCE_TYPE_NAME << " initialised twice");
00042         MYGUI_LOG(Info, "* Initialise: " << INSTANCE_TYPE_NAME);
00043 
00044         ResourceManager::getInstance().registerLoadXmlDelegate(XML_TYPE) = newDelegate(this, &LayoutManager::_load);
00045         layoutPrefix = "";
00046         layoutParent = nullptr;
00047 
00048         MYGUI_LOG(Info, INSTANCE_TYPE_NAME << " successfully initialized");
00049         mIsInitialise = true;
00050     }
00051 
00052     void LayoutManager::shutdown()
00053     {
00054         if (!mIsInitialise) return;
00055         MYGUI_LOG(Info, "* Shutdown: " << INSTANCE_TYPE_NAME);
00056 
00057         ResourceManager::getInstance().unregisterLoadXmlDelegate(XML_TYPE);
00058 
00059         MYGUI_LOG(Info, INSTANCE_TYPE_NAME << " successfully shutdown");
00060         mIsInitialise = false;
00061     }
00062 
00063     VectorWidgetPtr& LayoutManager::load(const std::string& _file)
00064     {
00065         mVectorWidgetPtr.clear();
00066         ResourceManager::getInstance()._loadImplement(_file, true, XML_TYPE, INSTANCE_TYPE_NAME);
00067         return mVectorWidgetPtr;
00068     }
00069 
00070     void LayoutManager::_load(xml::ElementPtr _node, const std::string& _file, Version _version)
00071     {
00072 #if MYGUI_DEBUG_MODE == 1
00073         MYGUI_LOG(Info, "load layout '" << _file << "'");
00074 #endif
00075         parseLayout(mVectorWidgetPtr, _node);
00076     }
00077 
00078     VectorWidgetPtr& LayoutManager::loadLayout(const std::string& _file, const std::string& _prefix, Widget* _parent)
00079     {
00080         static VectorWidgetPtr widgets;
00081         widgets.clear();
00082 
00083         layoutPrefix = _prefix;
00084         layoutParent = _parent;
00085         widgets = load(_file);
00086         layoutPrefix = "";
00087         layoutParent = nullptr;
00088         return widgets;
00089     }
00090 
00091     void LayoutManager::unloadLayout(VectorWidgetPtr& _widgets)
00092     {
00093         WidgetManager::getInstance().destroyWidgets(_widgets);
00094     }
00095 
00096     void LayoutManager::parseLayout(VectorWidgetPtr& _widgets, xml::ElementPtr _root)
00097     {
00098         // берем детей и крутимся
00099         xml::ElementEnumerator widget = _root->getElementEnumerator();
00100         while (widget.next("Widget")) parseWidget(_widgets, widget, layoutParent);
00101     }
00102 
00103     void LayoutManager::parseWidget(VectorWidgetPtr& _widgets, xml::ElementEnumerator& _widget, Widget* _parent)
00104     {
00105         // парсим атрибуты виджета
00106         std::string widgetType, widgetSkin, widgetName, widgetLayer, tmp;
00107 
00108         _widget->findAttribute("type", widgetType);
00109         _widget->findAttribute("skin", widgetSkin);
00110         _widget->findAttribute("layer", widgetLayer);
00111 
00112         Align align = Align::Default;
00113         if (_widget->findAttribute("align", tmp)) align = Align::parse(tmp);
00114 
00115         _widget->findAttribute("name", widgetName);
00116         if (!widgetName.empty()) widgetName = layoutPrefix + widgetName;
00117 
00118         WidgetStyle style = WidgetStyle::Child;
00119         if (_widget->findAttribute("style", tmp)) style = WidgetStyle::parse(tmp);
00120         if (_parent != nullptr && style != WidgetStyle::Popup) widgetLayer.clear();
00121 
00122         IntCoord coord;
00123         if (_widget->findAttribute("position", tmp)) coord = IntCoord::parse(tmp);
00124         else if (_widget->findAttribute("position_real", tmp))
00125         {
00126             if (_parent == nullptr || style == WidgetStyle::Popup)
00127                 coord = CoordConverter::convertFromRelative(FloatCoord::parse(tmp), Gui::getInstance().getViewSize());
00128             else
00129                 coord = CoordConverter::convertFromRelative(FloatCoord::parse(tmp), _parent->getSize());
00130         }
00131 
00132         Widget* wid;
00133         if (nullptr == _parent)
00134             wid = Gui::getInstance().createWidgetT(widgetType, widgetSkin, coord, align, widgetLayer, widgetName);
00135         else
00136             wid = _parent->createWidgetT(style, widgetType, widgetSkin, coord, align, widgetLayer, widgetName);
00137 
00138         if (layoutParent == _parent) _widgets.push_back(wid);
00139 
00140         // берем детей и крутимся
00141         xml::ElementEnumerator node = _widget->getElementEnumerator();
00142         while (node.next())
00143         {
00144             if (node->getName() == "Widget")
00145             {
00146                 parseWidget(_widgets, node, wid);
00147             }
00148             else if (node->getName() == "Property")
00149             {
00150                 wid->setProperty(node->findAttribute("key"), node->findAttribute("value"));
00151             }
00152             else if (node->getName() == "UserString")
00153             {
00154                 wid->setUserString(node->findAttribute("key"), node->findAttribute("value"));
00155             }
00156             else if (node->getName() == "Controller")
00157             {
00158                 const std::string& type = node->findAttribute("type");
00159                 MyGUI::ControllerItem* item = MyGUI::ControllerManager::getInstance().createItem(type);
00160                 if (item)
00161                 {
00162                     xml::ElementEnumerator prop = node->getElementEnumerator();
00163                     while (prop.next("Property"))
00164                     {
00165                         item->setProperty(prop->findAttribute("key"), prop->findAttribute("value"));
00166                     }
00167                     MyGUI::ControllerManager::getInstance().addItem(wid, item);
00168                 }
00169                 else
00170                 {
00171                     //LOG
00172                 }
00173             }
00174 
00175         }
00176     }
00177 
00178 } // namespace MyGUI