Ogre的SdkTray系统梗概

来源:互联网 发布:饮水机清洗 知乎 编辑:程序博客网 时间:2024/06/10 03:12

一、几个重要类的分析

enum TrayLocation //类,枚举widget窗口在Tray中摆放的位置。
enum ButtonState //类,枚举鼠标动作。
class SdkTrayListener //类,监听Tray中事件的接口。
class Widget// 类,是Tray中所以GUI控件的子类。
{
protected:
 Ogre::OverlayElement* mElement; //用于显示的OverlayElement对象
 TrayLocation mTrayLoc; //用于记录放置位置 
 SdkTrayListener* mListener; //用于相应鼠标动作,不同状态下显示GUI控件
 //其它的大多是一些static的通用函数。
 
 // callbacks 回调函数,SdkTrayManager 类出发鼠标消息时将调用下列函数
 virtual void _cursorPressed(const Ogre::Vector2& cursorPos) {}
 virtual void _cursorReleased(const Ogre::Vector2& cursorPos) {}
 virtual void _cursorMoved(const Ogre::Vector2& cursorPos) {}
 virtual void _focusLost() {}
}
class SdkTrayManager //类,是Tray系统的GUI控件管理工具
{
 //本来,SdkTrayManager 类没有这么麻烦,但是它把ogre的实例显示的界面也在这里实现了,所以就很大。
 //其实这些我们都是用不到的。比如:这个类实现了SdkTrayListener接口,就用不到。
 Ogre::OverlayContainer* mTrays[10];   // widget trays 用于存放所有GUI控件的OverlayContainer
 WidgetList mWidgets[10];              // widgets 分出不同位置存放GUI控件
 WidgetList mWidgetDeathRow;           // widget queue for deletion 用于存放待删除的GUI控件
 
 //下列函数,用于从RenderWindow中获得鼠标信息,向Tray中注入鼠标消息
 bool injectMouseDown(const OIS::MouseEvent& evt, OIS::MouseButtonID id);
 bool injectMouseUp(const OIS::MouseEvent& evt, OIS::MouseButtonID id);
 bool injectMouseMove(const OIS::MouseEvent& evt);
}

 

二、以OgreBites::SelectMenu类为例,介绍Tray系统GUI的应用


1、创建菜单:
调用 SdkTrayManager::createLongSelectMenu()函数创建菜单。
(函数createThickSelectMenu()等函数可以创建菜单,略)
创建出来的菜单对象指针存放在WidgetList mWidgets[10]; 中对应的WidgetList对象里面。
菜单的Ogre::OverlayContainer*存放在Ogre::OverlayContainer* mTrays[10]; 里面。

2、添加菜单项:
应用SelectMenu::addItem()和SelectMenu::setItems()函数

{
  OgreBites::SelectMenu* menu = mTrayMgr->createLongSelectMenu(OgreBites::TL_TOPRIGHT,
  "MainMenu",Ogre::DisplayString(L""), 120,112,10);
  Ogre::StringVector itemNames;
  itemNames.push_back("menuItem1");
  itemNames.push_back("menuItem2");
  menu->setItems(itemNames);
  menu->show();
}
现在显示菜单不相应任何动作。

3、将鼠标注入Tray
(1)SdkTrayManager::SdkTrayManager()中需要OIS::Mouse*做参数。
由于我使用的是MFC做界面,在生成一个OIS::Mouse*还要更新挺麻烦的。
查看代码发现mMouse只在SdkTrayManager::refreshCursor函数中被使用过。我不要Tray显示鼠标,所以

注释掉函数内容。
生成SdkTrayManager代码如下:

mTrayMgr = new OgreBites::SdkTrayManager("TrayGui", m_Window, 0,this);

(2)在鼠标消息的相应函数中,new 一个OIS::Mouse,填写对应信息,将MFC的鼠标消息转换成OIS::Mouse。将改OIS::Mouse对象注入Tray中。

//下列函数,用于从RenderWindow中获得鼠标信息,向Tray中注入鼠标消息
bool injectMouseDown(const OIS::MouseEvent& evt, OIS::MouseButtonID id);
bool injectMouseUp(const OIS::MouseEvent& evt, OIS::MouseButtonID id);
bool injectMouseMove(const OIS::MouseEvent& evt);

调用后,SdkTrayManager类的机制就会调用Widget类的回调函数,是GUI控件在鼠标悬停、按下等状态显示不同的界面。

class Widget
{
      // callbacks 回调函数,SdkTrayManager 类出发鼠标消息时将调用下列函数
      virtual void _cursorPressed(const Ogre::Vector2& cursorPos) {}
      virtual void _cursorReleased(const Ogre::Vector2& cursorPos) {}
      virtual void _cursorMoved(const Ogre::Vector2& cursorPos) {}
      virtual void _focusLost() {}
}
(3)实现class SdkTrayListener 类,监听Tray中事件的接口。
让监听类继承class SdkTrayListener 类。

另:由于我在创建SdkTrayManager类时没有给鼠标mMouse赋值,所以光标不会移动。

但是,SdkTrayListener 类中的鼠标位置点不是取从injectMouseDown()等函数的参数的值。是去光标显示的位置值。

修改如下:(其它注入函数类似)

bool injectMouseDown(const OIS::MouseEvent& evt, OIS::MouseButtonID id)
{
       ……
        Ogre::Vector2 cursorPos(evt.state.X.abs,evt.state.Y.abs);
         //Ogre::Vector2 cursorPos(mCursor->getLeft(), mCursor->getTop());

       ……
}

这时,编译生成,运行。可以看到鼠标悬停、按下、离开时OgreBites::SelectMenu类显示的变化。
但是,菜单不能实现任何功能,只是一个显示的界面。

(4)实现菜单功能
在 class SdkTrayListener 类的子类中重新函数void itemSelected()

void CMfcWin::itemSelected(OgreBites::SelectMenu* menu)
{
    Ogre::String menuSelected = menu->getSelectedItem();
    if (menuSelected=="menuItem1")
    {
          //menuItem1的实现功能
    }else if (menuSelected=="menuItem2")
    {
          //menuItem2的实现功能
    }
}

4、编译生成、运行。Ok。

三、深入OgreBites::SelectMenu类
由于我用的是OgreBites::SelectMenu类,所以了解比较多,记录一下,省的忘记。
下面为OgreBites::SelectMenu类各个成员变量具体功能。
其中,“下拉菜单”我的意思是,点击菜单头时候弹各个菜单项的那个显示面板。

  Ogre::BorderPanelOverlayElement* mSmallBox;  //菜单条目的小外框mSmallBox
  Ogre::BorderPanelOverlayElement* mExpandedBox; //下拉菜单面板
  Ogre::TextAreaOverlayElement* mTextArea;  //MenuCaption
  Ogre::TextAreaOverlayElement* mSmallTextArea; //菜单条目的字体显示mSmallTextArea
  Ogre::BorderPanelOverlayElement* mScrollTrack; //下拉菜单右边的滚动条
  Ogre::PanelOverlayElement* mScrollHandle;  //下拉菜单右边的滚动条 小滑块
  std::vector<Ogre::BorderPanelOverlayElement*> mItemElements;//下拉菜单条目列表
  bool mCursorOver;//鼠标是否在菜单上
  bool mExpanded;//是否在显示下拉菜单列表
  DisplayVector mItems; //菜单条目的文字信息记录vector

原创粉丝点击