GUI系统 布局管理器
1.布局管理器存在的理由:可以避免手动或者逐个调整控件位置
2.布局管理器的基本功能:调整同一容器下同一层次下各个控件的位置
3.布局管理器的基本接口:
A.控件加入
B.控件移除
C.控件排列
4.布局管理器和控件的关系
A.一个布局管理器负责1个或则多个控件的排列
B.具有控件容器语义的控件(例如面板)持有一个布局管理器
5.合适调用布局管理之布局?
A.持有的控件尺寸变化,移动或者用户显示的调用之时
6.可能的布局管理器类型
A>流式,中央布局,盒子,复杂类型,...
7.简单的布局管理器接口
所有类型的布局管理器都需要继承于UILayouter
其成员函数Arrange负责调配parent控件下的所有控件单元.
需要说明的是当容器控件加入一个新的控件的时候,其布局管理器就会调用AddWidget负责把新的控件加入布局管理器对象
举一个UI面板的例子:
/// UI面板(容器)
class G_DLL_API Panel : public Widget
{
public :
Panel( const Rectf & rect,Widget * parent, const engine_string & text = " Panel " );
virtual ~ Panel();
public :
// //
/// 加入一个子窗体
// //
Panel & AddChildWidget(Widget * widget)
{
windows_.push_back(widget);
layouter_ -> AddWidget(widget);
return * this ;
}
Panel & AddChildWidget(Widget * widget, const UILayoutInfo & info)
{
windows_.push_back(widget);
layouter_ -> AddWidget(widget,info);
return * this ;
}
// //
/// 控件移除
// //
Panel & RemoveChildWidget(Widget * widget)
{
windows_.remove(widget);
layouter_ -> RemoveWidget(widget);
return * this ;
}
// //
/// 控件排列
// //
Panel & ArrangeChildren()
{
layouter_ -> Arrange( this );
return * this ;
}
// //
/// 加载布局管理器
// //
Panel & SetLayouter(UILayouter * layouter); 在我设计的时候主要参考了2个GUI库,glooey,opengl gui lib
目前商业上使用的开源CEGUI过于复杂 比很多游戏引擎都大 让人难以容忍
1.布局管理器存在的理由:可以避免手动或者逐个调整控件位置
2.布局管理器的基本功能:调整同一容器下同一层次下各个控件的位置
3.布局管理器的基本接口:
A.控件加入
B.控件移除
C.控件排列
4.布局管理器和控件的关系
A.一个布局管理器负责1个或则多个控件的排列
B.具有控件容器语义的控件(例如面板)持有一个布局管理器
5.合适调用布局管理之布局?
A.持有的控件尺寸变化,移动或者用户显示的调用之时
6.可能的布局管理器类型
A>流式,中央布局,盒子,复杂类型,...
7.简单的布局管理器接口
/
//
/// UI布局信息基类
/ //
class UILayoutInfo
{
public :
UILayoutInfo(){}
virtual ~ UILayoutInfo(){}
public :
virtual engine_string GetLayouttType() const = 0 ;
};
/ //
/// 定义UI布局管理器基类
/ //
class UILayouter
{
public :
UILayouter(){}
virtual ~ UILayouter(){}
public :
// //
/// 增加一个窗体到布局管理区
// //
virtual UILayouter & AddWidget(Widget * widget) = 0 ;
virtual UILayouter & AddWidget(Widget * widget, const UILayoutInfo & )
{
AddWidget(widget);
return * this ;
}
// //
/// 控件移除和重新排列
// //
virtual UILayouter & RemoveWidget(Widget * widget) = 0 ;
virtual UILayouter & Arrange(Widget * parent) = 0 ;
};
/// UI布局信息基类
/ //
class UILayoutInfo
{
public :
UILayoutInfo(){}
virtual ~ UILayoutInfo(){}
public :
virtual engine_string GetLayouttType() const = 0 ;
};
/ //
/// 定义UI布局管理器基类
/ //
class UILayouter
{
public :
UILayouter(){}
virtual ~ UILayouter(){}
public :
// //
/// 增加一个窗体到布局管理区
// //
virtual UILayouter & AddWidget(Widget * widget) = 0 ;
virtual UILayouter & AddWidget(Widget * widget, const UILayoutInfo & )
{
AddWidget(widget);
return * this ;
}
// //
/// 控件移除和重新排列
// //
virtual UILayouter & RemoveWidget(Widget * widget) = 0 ;
virtual UILayouter & Arrange(Widget * parent) = 0 ;
};
所有类型的布局管理器都需要继承于UILayouter
其成员函数Arrange负责调配parent控件下的所有控件单元.
需要说明的是当容器控件加入一个新的控件的时候,其布局管理器就会调用AddWidget负责把新的控件加入布局管理器对象
举一个UI面板的例子:
/// UI面板(容器)
class G_DLL_API Panel : public Widget
{
public :
Panel( const Rectf & rect,Widget * parent, const engine_string & text = " Panel " );
virtual ~ Panel();
public :
// //
/// 加入一个子窗体
// //
Panel & AddChildWidget(Widget * widget)
{
windows_.push_back(widget);
layouter_ -> AddWidget(widget);
return * this ;
}
Panel & AddChildWidget(Widget * widget, const UILayoutInfo & info)
{
windows_.push_back(widget);
layouter_ -> AddWidget(widget,info);
return * this ;
}
// //
/// 控件移除
// //
Panel & RemoveChildWidget(Widget * widget)
{
windows_.remove(widget);
layouter_ -> RemoveWidget(widget);
return * this ;
}
// //
/// 控件排列
// //
Panel & ArrangeChildren()
{
layouter_ -> Arrange( this );
return * this ;
}
// //
/// 加载布局管理器
// //
Panel & SetLayouter(UILayouter * layouter);
目前商业上使用的开源CEGUI过于复杂 比很多游戏引擎都大 让人难以容忍