MyGUI  3.2.1
MyGUI_ResourceLayout.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_ResourceLayout.h"
00009 #include "MyGUI_CoordConverter.h"
00010 #include "MyGUI_RenderManager.h"
00011 #include "MyGUI_ControllerManager.h"
00012 #include "MyGUI_LayoutManager.h"
00013 #include "MyGUI_Widget.h"
00014 #include "MyGUI_Gui.h"
00015 
00016 namespace MyGUI
00017 {
00018 
00019     ResourceLayout::ResourceLayout()
00020     {
00021     }
00022 
00023     ResourceLayout::ResourceLayout(xml::ElementPtr _node, const std::string& _fileName)
00024     {
00025         // FIXME hardcoded version
00026         deserialization(_node, Version(1, 0, 0));
00027         mResourceName = _fileName;
00028     }
00029 
00030     void ResourceLayout::deserialization(xml::ElementPtr _node, Version _version)
00031     {
00032         Base::deserialization(_node, _version);
00033 
00034         mLayoutData.clear();
00035 
00036         xml::ElementEnumerator widget = _node->getElementEnumerator();
00037         while (widget.next("Widget"))
00038             mLayoutData.push_back(parseWidget(widget));
00039     }
00040 
00041     WidgetInfo ResourceLayout::parseWidget(xml::ElementEnumerator& _widget)
00042     {
00043         WidgetInfo widgetInfo;
00044 
00045         std::string tmp;
00046 
00047         _widget->findAttribute("type", widgetInfo.type);
00048         _widget->findAttribute("skin", widgetInfo.skin);
00049         _widget->findAttribute("layer", widgetInfo.layer);
00050 
00051         if (_widget->findAttribute("align", tmp)) widgetInfo.align = Align::parse(tmp);
00052 
00053         _widget->findAttribute("name", widgetInfo.name);
00054 
00055         if (_widget->findAttribute("style", tmp)) widgetInfo.style = WidgetStyle::parse(tmp);
00056 
00057         IntCoord coord;
00058         if (_widget->findAttribute("position", tmp))
00059         {
00060             widgetInfo.intCoord = IntCoord::parse(tmp);
00061             widgetInfo.positionType = WidgetInfo::Pixels;
00062         }
00063         else if (_widget->findAttribute("position_real", tmp))
00064         {
00065             widgetInfo.floatCoord = FloatCoord::parse(tmp);
00066             widgetInfo.positionType = WidgetInfo::Relative;
00067         }
00068 
00069         // берем детей и крутимся
00070         xml::ElementEnumerator node = _widget->getElementEnumerator();
00071         while (node.next())
00072         {
00073             if (node->getName() == "Widget")
00074             {
00075                 widgetInfo.childWidgetsInfo.push_back(parseWidget(node));
00076             }
00077             else if (node->getName() == "Property")
00078             {
00079                 widgetInfo.properties.push_back(PairString(node->findAttribute("key"), node->findAttribute("value")));
00080             }
00081             else if (node->getName() == "UserString")
00082             {
00083                 widgetInfo.userStrings[node->findAttribute("key")] = node->findAttribute("value");
00084             }
00085             else if (node->getName() == "Controller")
00086             {
00087                 ControllerInfo controllerInfo;
00088                 controllerInfo.type = node->findAttribute("type");
00089 
00090                 xml::ElementEnumerator prop = node->getElementEnumerator();
00091                 while (prop.next("Property"))
00092                     controllerInfo.properties[prop->findAttribute("key")] = prop->findAttribute("value");
00093 
00094                 widgetInfo.controllers.push_back(controllerInfo);
00095             }
00096         }
00097 
00098         return widgetInfo;
00099     }
00100 
00101     VectorWidgetPtr ResourceLayout::createLayout(const std::string& _prefix, Widget* _parent)
00102     {
00103         VectorWidgetPtr widgets;
00104 
00105         for (VectorWidgetInfo::iterator iter = mLayoutData.begin(); iter != mLayoutData.end(); ++iter)
00106         {
00107             Widget* widget = createWidget(*iter, _prefix, _parent);
00108             widgets.push_back(widget);
00109         }
00110 
00111         return widgets;
00112     }
00113 
00114     Widget* ResourceLayout::createWidget(const WidgetInfo& _widgetInfo, const std::string& _prefix, Widget* _parent, bool _template)
00115     {
00116         std::string widgetName = _widgetInfo.name;
00117         WidgetStyle style = _widgetInfo.style;
00118         std::string widgetLayer = _widgetInfo.layer;
00119 
00120         if (!widgetName.empty()) widgetName = _prefix + widgetName;
00121 
00122         if (_parent != nullptr && style != WidgetStyle::Popup) widgetLayer.clear();
00123         if (_parent == nullptr && widgetLayer.empty())
00124         {
00125             MYGUI_LOG(Warning, "Root widget's layer is not specified, widget won't be visible. Specify layer or parent or attach it to another widget after load." << " [" << LayoutManager::getInstance().getCurrentLayout() << "]");
00126         }
00127 
00128         IntCoord coord;
00129         if (_widgetInfo.positionType == WidgetInfo::Pixels) coord = _widgetInfo.intCoord;
00130         else if (_widgetInfo.positionType == WidgetInfo::Relative)
00131         {
00132             if (_parent == nullptr || style == WidgetStyle::Popup)
00133                 coord = CoordConverter::convertFromRelative(_widgetInfo.floatCoord, RenderManager::getInstance().getViewSize());
00134             else
00135                 coord = CoordConverter::convertFromRelative(_widgetInfo.floatCoord, _parent->getClientCoord().size());
00136         }
00137 
00138         Widget* wid;
00139         if (nullptr == _parent)
00140             wid = Gui::getInstance().createWidgetT(_widgetInfo.type, _widgetInfo.skin, coord, _widgetInfo.align, widgetLayer, widgetName);
00141         else if (_template)
00142             wid = _parent->_createSkinWidget(style, _widgetInfo.type, _widgetInfo.skin, coord, _widgetInfo.align, widgetLayer, widgetName);
00143         else
00144             wid = _parent->createWidgetT(style, _widgetInfo.type, _widgetInfo.skin, coord, _widgetInfo.align, widgetLayer, widgetName);
00145 
00146         for (VectorStringPairs::const_iterator iter = _widgetInfo.properties.begin(); iter != _widgetInfo.properties.end(); ++iter)
00147         {
00148             wid->setProperty(iter->first, iter->second);
00149         }
00150 
00151         for (MapString::const_iterator iter = _widgetInfo.userStrings.begin(); iter != _widgetInfo.userStrings.end(); ++iter)
00152         {
00153             wid->setUserString(iter->first, iter->second);
00154             if (!_template)
00155                 LayoutManager::getInstance().eventAddUserString(wid, iter->first, iter->second);
00156         }
00157 
00158         for (VectorWidgetInfo::const_iterator iter = _widgetInfo.childWidgetsInfo.begin(); iter != _widgetInfo.childWidgetsInfo.end(); ++iter)
00159         {
00160             createWidget(*iter, _prefix, wid);
00161         }
00162 
00163         for (std::vector<ControllerInfo>::const_iterator iter = _widgetInfo.controllers.begin(); iter != _widgetInfo.controllers.end(); ++iter)
00164         {
00165             MyGUI::ControllerItem* item = MyGUI::ControllerManager::getInstance().createItem(iter->type);
00166             if (item)
00167             {
00168                 for (MapString::const_iterator iterProp = iter->properties.begin(); iterProp != iter->properties.end(); ++iterProp)
00169                 {
00170                     item->setProperty(iterProp->first, iterProp->second);
00171                 }
00172                 MyGUI::ControllerManager::getInstance().addItem(wid, item);
00173             }
00174             else
00175             {
00176                 MYGUI_LOG(Warning, "Controller '" << iter->type << "' not found");
00177             }
00178         }
00179 
00180         return wid;
00181     }
00182 
00183     const VectorWidgetInfo& ResourceLayout::getLayoutData() const
00184     {
00185         return mLayoutData;
00186     }
00187 
00188 } // namespace MyGUI