Gui 与 PointerManger 继承关系如下图它们有一个共同点是都继承与IWidgetCreator
同样为众多基类的Widget class 继承与这两个。如图
而IWidgetCreator有一个纯虚函数(接口肯定是纯虚的。)
protected:
virtual Widget* baseCreateWidget(
WidgetStyle _style,
const std::string& _type,
const std::string& _skin,
const IntCoord& _coord,
Align _align,
const std::string& _layer,
const std::string& _name) = 0;
上述三个类的实现函数都调用了LayerManager的
http://blog.csdn.net/geometry_/article/details/7324348 有介绍
if (!_layer.empty())
LayerManager::getInstance().attachToLayerNode(_layer, widget);
在widget 创建的时候渲染对象已经被添加到LayerManager的layerNode 中,
Widget多重继承其一是LayerItem。这在渲染中起的角色重大。
另外有一个疑问点是非基类中间接继承Widget中的Message类
也对LayerManager:: 其进行了显式的调用
这里先暂时做一个小猜测,其他Widget子类是通过其来调用创建Widget?
通过模板
Widget* createWidgetT(const std::string& _type, const std::string& _skin, const IntCoord& _coord, Align _align, const std::string& _name = "");
/** See Widget::createWidgetT(const std::string& _type, const std::string& _skin, const IntCoord& _coord, Align _align, const std::string& _name = "") */
Widget* createWidgetT(const std::string& _type, const std::string& _skin, int _left, int _top, int _width, int _height, Align _align, const std::string& _name = "");
/** Create widget using coordinates relative to parent. see Widget::createWidgetT(const std::string& _type, const std::string& _skin, const IntCoord& _coord, Align _align, const std::string& _name = "") */
Widget* createWidgetRealT(const std::string& _type, const std::string& _skin, const FloatCoord& _coord, Align _align, const std::string& _name = "");
/** Create widget using coordinates relative to parent. see Widget::createWidgetT(const std::string& _type, const std::string& _skin, const IntCoord& _coord, Align _align, const std::string& _name = "") */
Widget* createWidgetRealT(const std::string& _type, const std::string& _skin, float _left, float _top, float _width, float _height, Align _align, const std::string& _name = "");
// templates for creating widgets by type
/** Same as Widget::createWidgetT but return T pointer instead of Widget* */
template <typename T>
T* createWidget(const std::string& _skin, const IntCoord& _coord, Align _align, const std::string& _name = "")
{
return static_cast<T*>(createWidgetT(T::getClassTypeName(), _skin, _coord, _align, _name));
}
/** Same as Widget::createWidgetT but return T pointer instead of Widget* */
template <typename T>
T* createWidget(const std::string& _skin, int _left, int _top, int _width, int _height, Align _align, const std::string& _name = "")
{
return static_cast<T*>(createWidgetT(T::getClassTypeName(), _skin, IntCoord(_left, _top, _width, _height), _align, _name));
}
/** Same as Widget::createWidgetRealT but return T* instead of Widget* */
template <typename T>
T* createWidgetReal(const std::string& _skin, const FloatCoord& _coord, Align _align, const std::string& _name = "")
{
return static_cast<T*>(createWidgetRealT(T::getClassTypeName(), _skin, _coord, _align, _name));
}
/** Same as Widget::createWidgetRealT but return T* instead of Widget* */
template <typename T>
T* createWidgetReal(const std::string& _skin, float _left, float _top, float _width, float _height, Align _align, const std::string& _name = "")
{
return static_cast<T*>(createWidgetRealT(T::getClassTypeName(), _skin, _left, _top, _width, _height, _align, _name));
}
/** Create child widget
@param _style Child, Popup or Overlapped widget style
@param _type widget type
@param _skin widget skin
@param _coord int coordinates of widget (_left, _top, _width, _height)
@param _align widget align (possible values can be found in enum Align)
@param _name if needed (you can use it for finding widget by name later)
*/
Widget* createWidgetT(WidgetStyle _style, const std::string& _type, const std::string& _skin, const IntCoord& _coord, Align _align, const std::string& _layer = "", const std::string& _name = "");
/** Same as Widget::createWidgetT but return T* instead of Widget* */
template <typename T>
T* createWidget(WidgetStyle _style, const std::string& _skin, const IntCoord& _coord, Align _align, const std::string& _layer = "", const std::string& _name = "")
{
return static_cast<T*>(createWidgetT(_style, T::getClassTypeName(), _skin, _coord, _align, _layer, _name));
}
最终需要调用
Widget* Widget::baseCreateWidget(WidgetStyle _style, const std::string& _type, const std::string& _skin, const IntCoord& _coord, Align _align, const std::string& _layer, const std::string& _name)
{
Widget* widget = WidgetManager::getInstance().createWidget(_style, _type, _skin, _coord, _align, this,
_style == WidgetStyle::Popup ? nullptr : this, this, _name);
mWidgetChild.push_back(widget);
// присоединяем виджет с уровню
if (!_layer.empty() && widget->isRootWidget()) LayerManager::getInstance().attachToLayerNode(_layer, widget);
return widget;
}
进行创建!
不过需要进一步的进行分析;)