GUI系統(tǒng) 布局管理器
1.布局管理器存在的理由:可以避免手動(dòng)或者逐個(gè)調(diào)整控件位置
2.布局管理器的基本功能:調(diào)整同一容器下同一層次下各個(gè)控件的位置
3.布局管理器的基本接口:
A.控件加入
B.控件移除
C.控件排列
4.布局管理器和控件的關(guān)系
A.一個(gè)布局管理器負(fù)責(zé)1個(gè)或則多個(gè)控件的排列
B.具有控件容器語(yǔ)義的控件(例如面板)持有一個(gè)布局管理器
5.合適調(diào)用布局管理之布局?
A.持有的控件尺寸變化,移動(dòng)或者用戶顯示的調(diào)用之時(shí)
6.可能的布局管理器類型
A>流式,中央布局,盒子,復(fù)雜類型,...
7.簡(jiǎn)單的布局管理器接口
///////////////////////////////////////////////////////////
/// UI布局信息基類
///////////////////////////////////////////////////////////
class UILayoutInfo
{
public:
UILayoutInfo(){}
virtual ~UILayoutInfo(){}
public:
virtual engine_string GetLayouttType()const = 0;
};
///////////////////////////////////////////////////////////
/// 定義UI布局管理器基類
///////////////////////////////////////////////////////////
class UILayouter
{
public:
UILayouter(){}
virtual ~UILayouter(){}
public:
////////////////////////////////////////////////////////
/// 增加一個(gè)窗體到布局管理區(qū)
////////////////////////////////////////////////////////
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
其成員函數(shù)Arrange負(fù)責(zé)調(diào)配parent控件下的所有控件單元.
需要說(shuō)明的是當(dāng)容器控件加入一個(gè)新的控件的時(shí)候,其布局管理器就會(huì)調(diào)用AddWidget負(fù)責(zé)把新的控件加入布局管理器對(duì)象
舉一個(gè)UI面板的例子:
////////////////////////////////////////////////////////////
/// UI面板(容器)
////////////////////////////////////////////////////////////
class G_DLL_API Panel : public Widget
{
public:
Panel(const Rectf& rect,Widget* parent,const engine_string& text = "Panel");
virtual ~Panel();
public:
////////////////////////////////////////////////////////
/// 加入一個(gè)子窗體
////////////////////////////////////////////////////////
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);
在我設(shè)計(jì)的時(shí)候主要參考了2個(gè)GUI庫(kù),glooey,opengl gui lib
目前商業(yè)上使用的開(kāi)源CEGUI過(guò)于復(fù)雜 比很多游戲引擎都大 讓人難以容忍