作者:Ionware
译者:akinggw
欢迎来到我的GUI系列文章的第一篇。我从一个非常高的角度更新了他们,这样是为了便于你喜欢上她并且能很快明白。
她是一个OPENGL GUI,只需要OPENGL去渲染她的组件和建立纹理/材质,但从某种意义上说她并不依赖与OPENGL
目录
l 简介
l 类定义和结构
l 画一个东东
l 处理输入
l 下载
简介
什么是GUI?图形用户界面。正确,还有什么?好的,让我们看一下标准的WINDOWS。她像什么?就像一个带边框,颜色和纹理的简单的多边形。因此,假设我们的GUI也将是一个2D多边形(四边形)。那我们需要怎样做呢?让我们看一下。
类定义和结构
我们的第一个类,是的,CGUIElement,是其它控制的基础。我们将以后为它添加更多的功能。让我们看一下这个类:
class CGUIElement: public CXMLResource,public CdoubleList<CGUIElement *>
{
CREATOR(CGUI);
CREATOR(CGUIBorder);
Public:
CGUIElement();
Virtual ~CGUIElement();
Virtual void Initialize();
Virtual int Create(CGUIElement *pParent,tRect WidgetRect,Ctexture *pTexture = NULL,Cmaterial *pMaterial = NULL,bool bBorder = false);
Virtual int LoadXML(TiXmlNode *pDateNode,Cstring strFilename);
Virtual int SaveXML(TIXmlNode *pDateNode,Cstring strFilename);
Virtual void Draw();
Virtual void Destroy();
Virtual void ProcessMessages();
Virtual void ProcessMessage(tGUIMessage& Message);
Virtual int Resize(tRect& NewRect);
Virtual int OnKeyDown(UINT uiKeyCode);
Virtual int OnKeyUp(UINT uiKeyCode);
Virtual int OnMove(UINT x,UINT y);
Virtual int OnMouseMove(UINT x,UINT y);
Virtual int OnLMouseDown(UINT x, UINT y);
Virtual int OnLMouseUp(UINT x, UINT y);
Virtual int OnRMouseDown(UINT x,UINT y);
Virtual int OnRMouseUp(UINT x,UINT y);
UINT GetWidth();
Void SetWidth(UINT uiWidth);
UINT GetHeight();
Void Setheight(UINT uiHeight);
CGUIElement *GetChild(UINT uiIndex);
CGUIElement *GetChild(eGUIControlType eWidgetType);
CGUIElement *GetChild(TiXmlElement *pXMLElement);
UINT GetChildCount();
Void RemoveChild(CGUIElement *pChild);
Void HideSiblings(int iDeep = -1);
Void ShowSiblings(int iDeep = -1);
Void SetZOrder(UINT uiZOrder);
UINT GetZOrder();
Bool Visible();
void Hide();
void Show();
CGUIElement *GetParent();
Void Setparent(CGUIElement *pParent);
Void SetTexture(Ctexture *pTexture);
Ctexture *GetTexture();
Void SetMaterial(Cmaterial *pMaterial);
Cmaterial *GetMaterial();
Void SetTexCoord(UINT uiIndex,float U,float V);
Tvertex2f& GetTexCoord(UINT index);
CGUI *GetGUI();
Void SetRect(tRect& NewRect);
TRect& GetRect();
Void SetGUI(CGUI *pGUI);
EGUIControlType& GetType();
Void SetType(eGUIControlType eWidgetType);
Void SetFlag(eGUIFlag eFlag,bool bSet);
Bool IsFlagSet(eGUIFlag eFlag);
Bool IsChild(CGUIElement *pElement);
Bool IsAutoCalc();
Void SetAutoCalc(bool bAutoCalc);
Virtual bool IsOfType(eEntityType eType);
Cstring GetElementType(); #ifdef GUI_USE_ACTIVE_INACTIVE bool IsActive() { return m_bActive; }; void Activate() { m_bActive = true;}; void Deactivate() {m_bActive = false;}; #endif protected: #ifndef GUI_USE_ACTIVE_INACTIVE Cmaterial *m_pMaterial; //组件的材质指针 #elif COLORREF m_ActiveColor; //材质活动的颜色 COLORREF m_InactiveColor; //材质静止的颜色 Bool m_bActive; //材质是活动或静止 #endif //组件的关键参数 eGUIControlType m_eControlType; //组件的类型 bool m_bAutoCalc; //自动计算标志:用于很多方面 CGUIElement *m_pParent; //父亲组件 CGUI *m_pGUI; //根GUI DWORD m_dwFlags; //组件标志 Ctexture *m_pTexture; //组件的纹理指针 Tvertex2fm_texCoord[4]; //组件的纹理坐标 Bool m_bVisible; //组件的可视标志
};
这段代码显示的结构如下:
http://openglgui.sourceforge.net/images/gui_tut1_img1.jpg
是的,这是一个非常大的类,她是我们一切的基础,因此,现在我们看一下她的功能函数。
首先,我们需要初始化一个组件,这个完全可以在构造函数中完成,但是我选择在Initialize()函数中完成她。
正如你所看到的,我们有自己的消息处理类,因此每个类都有自己的消息处理函数ProcessMessages()在每次画的时候处理它,并且寻找与她相关的消息。例如,按下一个按钮后会出现一个下拉菜单,你是否会选择她其中的一个选项。
每个组件也有一个导入/保存函数,但是并不需要每次都重写她。相反,我们使用一个通用的类去保存她的组件参数,然后在根结点时保存整棵树的参数。同样,我们也有自己的键盘/鼠标处理函数。
整个GUI的结构如下:
http://openglgui.sourceforge.net/images/gui_tut1_img2.jpg |