GUI系统 布局管理器
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 ;
};

所有类型的布局管理器都需要继承于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过于复杂 比很多游戏引擎都大 让人难以容忍