ogre SdkTray

来源:互联网 发布:淘宝情趣用品店名大全 编辑:程序博客网 时间:2024/05/22 14:18

要使用sdkTray的界面,首先要创建一个OgreBites::SdkTrayManager对象;

 OgreBites::SdkTrayManager* mTrayMgr;
 //第二个参数是Ogre::RenderWindow*,第三个参数是OIS::Mouse* ,
 //第四个参数是监听器:OgreBites::SdkTrayListener,
 mTrayMgr = new OgreBites::SdkTrayManager("InterfaceName", mWindow, mMouse, this);

     监听器的原始定义:
     class SdkTrayListener
     {
     public:
  virtual ~SdkTrayListener() {}
  virtual void buttonHit(Button* button) {}
  virtual void itemSelected(SelectMenu* menu) {}
  virtual void labelHit(Label* label) {}
  virtual void sliderMoved(Slider* slider) {}
  virtual void checkBoxToggled(CheckBox* box) {}
  virtual void okDialogClosed(const Ogre::DisplayString& message) {}
  virtual void yesNoDialogClosed(const Ogre::DisplayString& question, bool yesHit) {}
     };

 一般由BaseApplication类继承这个监听器,并重写里面的虚函数:

 注意一般需要在BaseApplication::frameRenderingQueued,显示的调用mTrayMgr->frameRenderingQueued(evt);
  SdkTrayManager对象的frameRenderingQueued函数只是更新帧状态。


 要使SdkTrayManager里面的控件能够响应各种鼠标键盘事件,需要在这些鼠标键盘事件发生时调用相应的SdkTrayManager函数:
 其实主要是鼠标事件,键盘事件的话,就一个keyPressed事件,对于这个事件首先要判断:
 if (mTrayMgr->isDialogVisible()) return true;//如果SdkTrayManager的对话框弹出来了,任何其他按键事件都不做处理了,看来
 这是个模态对话框啊,哈哈。

 对于各种鼠标事件,在事件处理函数的开头调用:
 if (mTrayMgr->injectMouseMove(arg)) return true;
 if (mTrayMgr->injectMouseDown(arg, id)) return true;
 if (mTrayMgr->injectMouseUp(arg, id)) return true;

 然后再做其他方面的处理。

   再看一下其他的有用的SdkTrayManager函数:
 showAll();//这个函数里面是这样的:{showBackdrop(),showTrays(),showCursor()}
 hideAll();//因此,貌似sdkTray里面有三种东西:backdrop,trays,cursor,控件都是放在trays里面的。

 有一个很有用的函数:Ogre::Ray getCursorRay(Ogre::Camera* cam)//获得屏幕光标处到场景的一条射线。 


 //根据控件的指针,将控件放在屏幕的某一个位置
 void moveWidgetToTray(Widget* widget, TrayLocation trayLoc, int place = -1)
 //根据名字
 void moveWidgetToTray(const Ogre::String& name, TrayLocation trayLoc, unsigned int place = -1)
 //将控件移出屏幕
 void removeWidgetFromTray(Widget* widget)
 void removeWidgetFromTray(const Ogre::String& name)
 void removeWidgetFromTray(TrayLocation trayLoc, const Ogre::String& name)
 //将某个位置的所有控件移出屏幕
 void clearTray(TrayLocation trayLoc)
 //将所有控件移出屏幕
 void clearAllTrays()

 //还有很多创建各种控件的函数,以及各种监听器的虚函数的重写。

有了管理器对象就可以做一些事情了:
   1
 mTrayMgr->showFrameStats(OgreBites::TL_BOTTOMLEFT);//显示帧状态
     mTrayMgr->showLogo(OgreBites::TL_BOTTOMRIGHT); //显示ogre log
     mTrayMgr->hideCursor(); //隐藏光标

   //下面可以创建各种控件了,各种控件都继承Widget类
 这个widget类有一些比较实用的函数:
 //对一个字符串进行裁剪,使它可以显示在某个文本区域里面。
 static void fitCaptionToArea(const Ogre::DisplayString& caption, Ogre::TextAreaOverlayElement* area, Ogre::Real maxWidth)
 //获得文本overlayelement的标题的宽度
 static Ogre::Real getCaptionWidth(const Ogre::DisplayString& caption, Ogre::TextAreaOverlayElement* area)

 Ogre::OverlayElement* getOverlayElement()//获得overlayelement
 static Ogre::Vector2 cursorOffset(Ogre::OverlayElement* element, const Ogre::Vector2& cursorPos)
 static bool isCursorOver(Ogre::OverlayElement* element, const Ogre::Vector2& cursorPos, Ogre::Real voidBorder = 0)

 static void nukeOverlayElement(Ogre::OverlayElement* element) //删除本widget里面的所有overlayelement
 
 const Ogre::String& getName() //获得名字
 TrayLocation getTrayLocation() //获得位置
 hide(),show(),隐藏和显示
 bool isVisible();
 //这个类还有各种响应鼠标事件的虚函数,需要在各种控件里面重写,各种控件也都重写了这些虚函数
 //鼠标移动,旋转,焦点丢失等等这些效果都不需要我们操心了。

 Widget类里面有个SdkTrayListener* mListener,SdkTrayManager在创建Widget类对象的时候会将他自己的SdkTrayListener* mListener
 传递给刚创建的Widget的mListener成员。


   2创建参数面板:
 Ogre::StringVector items;
     items.push_back("cam.pX"); //第一个参数
     items.push_back("cam.pY"); //第二个参数
     items.push_back("cam.pZ");
 mDetailsPanel = mTrayMgr->createParamsPanel(OgreBites::TL_NONE, "DetailsPanel", 200, items);//200是面板的宽度
 mDetailsPanel->setParamValue(1, "Bilinear"); //通过索引设置某一项参数的值,有个函数可以通过参数名设置参数的值
     mDetailsPanel->getParamValue(2); //通过索引来获得参数值,也可以通过参数名来获得值。


   3创建菜单:
 SelectMenu* selectMenu = mTrayMgr->createLongSelectMenu();
 添加菜单项:
 selectMenu->addItem(Ogre::String item);

 菜单类class SelectMenu : public Widget
 有各种函数,。。。。自己去看,可以获得当前选择的菜单项,设置各种等等。
 他自己重写了Widget的各种响应鼠标事件的函数,因此鼠标在菜单上面的动作都能自动得到响应
 不需要我们去处理了,我们只需要调用一个函数得到他当前选择的菜单项即可。


   4创建按钮
 OgreBites::Button* pBut = mTrayMgr->createButton(TL_TOPRIGHT, "名字", "标题", 像素宽度);
 //在其他地方可以直接通过控件的名字得到控件
 static_cast<OgreBites::Button*>(mTrayMgr->getWidget("PageButtonControl"))->setCaption(pageText);

 Button类只有一些获取设置button标题的一些函数。button最重要的是button按下事件响应。


 //控件按下之后总要改变一些东西吧,比如说改变某个变量的值等,这怎么实现呢?
 //也就是有没有控件的事件响应函数呢?
 我知道了,在他的_cursorReleased()函数里面调用了Widget类的mListener->buttonHit(this);
 这个mListener是SdkTrayListener*类型。
 这个mListener是谁给他赋值的呢,原来SdkTrayManager在创建各种Widget的时候,都会将自己的SdkTrayListener*成员赋值给
 Widget的mListener,因此这个buttonhit实际上时调用了SdkTrayManager中的mListener->buttonhit。
 而这个SdkTrayManager中的mListener是我们自己在创建SdkTrayManager对象时,将TutorialApplication指针传递了进去,
 TutorialApplication继承了SdkTrayListener,并重新了其中的buttonHit();

 所以现在可以知道了其实是TutorialApplication中重写的buttonHit()响应了按钮事件。
 
   5创建CheckBox:
 mTrayMgr->createCheckBox(TL_TOPLEFT, "SpinLightButton", "Spin Light", 175)->setChecked(true);
 这个CheckBox最重要的也是check状态变化响应函数,重写监听器的checkBoxToggled(CheckBox* cb)函数
 在里面获取cb的check状态,从而做出相应的反应。
 const Ogre::DisplayString& getCaption()
 void setCaption(const Ogre::DisplayString& caption)
 bool isChecked()
 void setChecked(bool checked, bool notifyListener = true)
 void toggle(bool notifyListener = true)
 就上面这些函数。

   6创建滑动条Slider:
 OgreBites::Slider* mslider = mTrayMgr->createThickSlider(......);
 对于slider控件,SdkTrayListener里面也有个虚函数需要重载:virtual void sliderMoved(Slider* slider) {}
 当然Slider类本身也有一些函数设置滑块的位置等。
 setRange();
 getValueCaption();
 void setValueCaption(const Ogre::DisplayString& caption)
 void setValue(Ogre::Real value, bool notifyListener = true);
 Ogre::Real getValue();
 const Ogre::DisplayString& getCaption()
 void setCaption(const Ogre::DisplayString& caption)
 就上面这些函数。