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