Ogre SdkTrays UI c++ code override with c# (.net2.0)

75499 ワード

c++ snap code
    /*
     -----------------------------------------------------------------------------
     This source file is part of OGRE
     -----------------------------------------------------------------------------
     */
    #ifndef __SdkTrays_H__
    #define __SdkTrays_H__

    #include "Ogre.h"
    #include "OgreFontManager.h"
    #include "OgreBorderPanelOverlayElement.h"
    #include "OgreTextAreaOverlayElement.h"
    #include <math.h>

    #if OGRE_COMPILER == OGRE_COMPILER_MSVC
    // TODO - remove this
    #   pragma warning (disable : 4244)
    #endif

    namespace OgreBites
    {
       enum TrayLocation   // enumerator values for widget tray anchoring locations
       {
          TL_TOPLEFT,
          TL_TOP,
          TL_TOPRIGHT,
          TL_LEFT,
          TL_CENTER,
          TL_RIGHT,
          TL_BOTTOMLEFT,
          TL_BOTTOM,
          TL_BOTTOMRIGHT,
          TL_NONE
       };

       enum ButtonState   // enumerator values for button states
       {
          BS_UP,
          BS_OVER,
          BS_DOWN
       };

       // forward widget class declarations
       class Widget;
       class Button;
       class SelectMenu;
       class Label;
       class Slider;
       class CheckBox;

       /*=============================================================================
       | Listener class for responding to tray events.
       =============================================================================*/


       /*=============================================================================
       | Abstract base class for all widgets.
       =============================================================================*/
       class Widget
       {
       public:
             
          Widget()
          {
             mTrayLoc = TL_NONE;
             mElement = 0;
             mListener = 0;
          }

          virtual ~Widget() {}

          void cleanup()
          {
             if (mElement) nukeOverlayElement(mElement);
             mElement = 0;
          }

          /*-----------------------------------------------------------------------------
          | Static utility method to recursively delete an overlay element plus
          | all of its children from the system.
          -----------------------------------------------------------------------------*/
          static void nukeOverlayElement(Ogre::OverlayElement* element)
          {
             Ogre::OverlayContainer* container = dynamic_cast<Ogre::OverlayContainer*>(element);
             if (container)
             {
                std::vector<Ogre::OverlayElement*> toDelete;

                Ogre::OverlayContainer::ChildIterator children = container->getChildIterator();
                while (children.hasMoreElements())
                {
                   toDelete.push_back(children.getNext());
                }

                for (unsigned int i = 0; i < toDelete.size(); i++)
                {
                   nukeOverlayElement(toDelete[i]);
                }
             }
             if (element)
             {
                Ogre::OverlayContainer* parent = element->getParent();
                if (parent) parent->removeChild(element->getName());
                Ogre::OverlayManager::getSingleton().destroyOverlayElement(element);
             }
          }

          /*-----------------------------------------------------------------------------
          | Static utility method to check if the cursor is over an overlay element.
          -----------------------------------------------------------------------------*/
          static bool isCursorOver(Ogre::OverlayElement* element, const Ogre::Vector2& cursorPos, Ogre::Real voidBorder = 0)
          {
             Ogre::OverlayManager& om = Ogre::OverlayManager::getSingleton();
                Ogre::Real l = element->_getDerivedLeft() * om.getViewportWidth();
                Ogre::Real t = element->_getDerivedTop() * om.getViewportHeight();
                Ogre::Real r = l + element->getWidth();
                Ogre::Real b = t + element->getHeight();

             return (cursorPos.x >= l + voidBorder && cursorPos.x <= r - voidBorder &&
                cursorPos.y >= t + voidBorder && cursorPos.y <= b - voidBorder);
          }

          /*-----------------------------------------------------------------------------
          | Static utility method used to get the cursor's offset from the center
          | of an overlay element in pixels.
          -----------------------------------------------------------------------------*/
          static Ogre::Vector2 cursorOffset(Ogre::OverlayElement* element, const Ogre::Vector2& cursorPos)
          {
             Ogre::OverlayManager& om = Ogre::OverlayManager::getSingleton();
             return Ogre::Vector2(cursorPos.x - (element->_getDerivedLeft() * om.getViewportWidth() + element->getWidth() / 2),
                cursorPos.y - (element->_getDerivedTop() * om.getViewportHeight() + element->getHeight() / 2));
          }

       
          void resourceGroupLoadStarted(const Ogre::String& groupName, size_t resourceCount)
          {
             mLoadInc = mGroupLoadProportion / resourceCount;
             mLoadBar->setCaption("Loading...");
    #if OGRE_PLATFORM != OGRE_PLATFORM_IPHONE
             mWindow->update();
    #endif
          }

          void resourceLoadStarted(const Ogre::ResourcePtr& resource)
          {
             mLoadBar->setComment(resource->getName());
    #if OGRE_PLATFORM != OGRE_PLATFORM_IPHONE
             mWindow->update();
    #endif
          }

          void resourceLoadEnded()
          {
             mLoadBar->setProgress(mLoadBar->getProgress() + mLoadInc);
    #if OGRE_PLATFORM != OGRE_PLATFORM_IPHONE
             mWindow->update();
    #endif
          }

          void worldGeometryStageStarted(const Ogre::String& description)
          {
             mLoadBar->setComment(description);
    #if OGRE_PLATFORM != OGRE_PLATFORM_IPHONE
             mWindow->update();
    #endif
          }

          void worldGeometryStageEnded()
          {
             mLoadBar->setProgress(mLoadBar->getProgress() + mLoadInc);
    #if OGRE_PLATFORM != OGRE_PLATFORM_IPHONE
             mWindow->update();
    #endif
          }

          void resourceGroupLoadEnded(const Ogre::String& groupName) {}

          /*-----------------------------------------------------------------------------
          | Toggles visibility of advanced statistics.
          -----------------------------------------------------------------------------*/
          void labelHit(Label* label)
          {
             if (mStatsPanel->getOverlayElement()->isVisible())
             {
                mStatsPanel->getOverlayElement()->hide();
                mFpsLabel->getOverlayElement()->setWidth(150);
                removeWidgetFromTray(mStatsPanel);
             }
             else
             {
                mStatsPanel->getOverlayElement()->show();
                mFpsLabel->getOverlayElement()->setWidth(180);
                moveWidgetToTray(mStatsPanel, mFpsLabel->getTrayLocation(), locateWidgetInTray(mFpsLabel) + 1);
             }
          }

          /*-----------------------------------------------------------------------------
          | Destroys dialog widgets, notifies listener, and ends high priority session.
          -----------------------------------------------------------------------------*/
          void buttonHit(Button* button)
          {
             if (mListener)
             {
                if (button == mOk) mListener->okDialogClosed(mDialog->getText());
                else mListener->yesNoDialogClosed(mDialog->getText(), button == mYes);
             }
             closeDialog();
          }

          /*-----------------------------------------------------------------------------
          | Processes mouse button down events. Returns true if the event was
          | consumed and should not be passed on to other handlers.
          -----------------------------------------------------------------------------*/
    #if OGRE_PLATFORM == OGRE_PLATFORM_IPHONE
          bool injectMouseDown(const OIS::MultiTouchEvent& evt)
    #else
          bool injectMouseDown(const OIS::MouseEvent& evt, OIS::MouseButtonID id)
    #endif
          {
    #if OGRE_PLATFORM != OGRE_PLATFORM_IPHONE
             // only process left button when stuff is visible
             if (!mCursorLayer->isVisible() || id != OIS::MB_Left) return false;
    #else
                // only process touches when stuff is visible
             if (!mCursorLayer->isVisible()) return false;
    #endif
             Ogre::Vector2 cursorPos(mCursor->getLeft(), mCursor->getTop());

             mTrayDrag = false;

             if (mExpandedMenu)   // only check top priority widget until it passes on
             {
                mExpandedMenu->_cursorPressed(cursorPos);
                if (!mExpandedMenu->isExpanded()) setExpandedMenu(0);
                return true;
             }

             if (mDialog)   // only check top priority widget until it passes on
             {
                mDialog->_cursorPressed(cursorPos);
                if (mOk) mOk->_cursorPressed(cursorPos);
                else
                {
                   mYes->_cursorPressed(cursorPos);
                   mNo->_cursorPressed(cursorPos);
                }
                return true;
             }

             for (unsigned int i = 0; i < 9; i++)   // check if mouse is over a non-null tray
             {
                if (mTrays[i]->isVisible() && Widget::isCursorOver(mTrays[i], cursorPos, 2))
                {
                   mTrayDrag = true;   // initiate a drag that originates in a tray
                   break;
                }
             }

             for (unsigned int i = 0; i < mWidgets[9].size(); i++)  // check if mouse is over a non-null tray's widgets
             {
                if (mWidgets[9][i]->getOverlayElement()->isVisible() &&
                   Widget::isCursorOver(mWidgets[9][i]->getOverlayElement(), cursorPos))
                {
                   mTrayDrag = true;   // initiate a drag that originates in a tray
                   break;
                }
             }

             if (!mTrayDrag) return false;   // don't process if mouse press is not in tray

             for (unsigned int i = 0; i < 10; i++)
             {
                if (!mTrays[i]->isVisible()) continue;

                for (unsigned int j = 0; j < mWidgets[i].size(); j++)
                {
                   Widget* w = mWidgets[i][j];
                   if (!w->getOverlayElement()->isVisible()) continue;
                   w->_cursorPressed(cursorPos);    // send event to widget

                   SelectMenu* m = dynamic_cast<SelectMenu*>(w);
                   if (m && m->isExpanded())       // a menu has begun a top priority session
                   {
                      setExpandedMenu(m);
                      return true;
                   }
                }
             }

             return true;   // a tray click is not to be handled by another party
          }

          /*-----------------------------------------------------------------------------
          | Processes mouse button up events. Returns true if the event was
          | consumed and should not be passed on to other handlers.
          -----------------------------------------------------------------------------*/
    #if OGRE_PLATFORM == OGRE_PLATFORM_IPHONE
          bool injectMouseUp(const OIS::MultiTouchEvent& evt)
    #else
          bool injectMouseUp(const OIS::MouseEvent& evt, OIS::MouseButtonID id)
    #endif
          {
    #if OGRE_PLATFORM != OGRE_PLATFORM_IPHONE
             // only process left button when stuff is visible
             if (!mCursorLayer->isVisible() || id != OIS::MB_Left) return false;
    #else
                // only process touches when stuff is visible
             if (!mCursorLayer->isVisible()) return false;
    #endif
             Ogre::Vector2 cursorPos(mCursor->getLeft(), mCursor->getTop());

             if (mExpandedMenu)   // only check top priority widget until it passes on
             {
                mExpandedMenu->_cursorReleased(cursorPos);
                return true;
             }

             if (mDialog)   // only check top priority widget until it passes on
             {
                mDialog->_cursorReleased(cursorPos);
                if (mOk) mOk->_cursorReleased(cursorPos);
                else
                {
                   mYes->_cursorReleased(cursorPos);
                   // very important to check if second button still exists, because first button could've closed the popup
                   if (mNo) mNo->_cursorReleased(cursorPos); 
                }
                return true;
             }

             if (!mTrayDrag) return false;    // this click did not originate in a tray, so don't process

             Widget* w;

             for (unsigned int i = 0; i < 10; i++)
             {
                if (!mTrays[i]->isVisible()) continue;

                for (unsigned int j = 0; j < mWidgets[i].size(); j++)
                {
                   w = mWidgets[i][j];
                   if (!w->getOverlayElement()->isVisible()) continue;
                   w->_cursorReleased(cursorPos);    // send event to widget
                }
             }

             mTrayDrag = false;   // stop this drag
             return true;         // this click did originate in this tray, so don't pass it on
          }

          /*-----------------------------------------------------------------------------
          | Updates cursor position. Returns true if the event was
          | consumed and should not be passed on to other handlers.
          -----------------------------------------------------------------------------*/
    #if OGRE_PLATFORM == OGRE_PLATFORM_IPHONE
          bool injectMouseMove(const OIS::MultiTouchEvent& evt)
    #else
          bool injectMouseMove(const OIS::MouseEvent& evt)
    #endif
          {
             if (!mCursorLayer->isVisible()) return false;   // don't process if cursor layer is invisible

                Ogre::Vector2 cursorPos(evt.state.X.abs, evt.state.Y.abs);
             mCursor->setPosition(cursorPos.x, cursorPos.y);

             if (mExpandedMenu)   // only check top priority widget until it passes on
             {
                mExpandedMenu->_cursorMoved(cursorPos);
                return true;
             }

             if (mDialog)   // only check top priority widget until it passes on
             {
                mDialog->_cursorMoved(cursorPos);
                if (mOk) mOk->_cursorMoved(cursorPos);
                else
                {
                   mYes->_cursorMoved(cursorPos);
                   mNo->_cursorMoved(cursorPos);
                }
                return true;
             }

             Widget* w;

             for (unsigned int i = 0; i < 10; i++)
             {
                if (!mTrays[i]->isVisible()) continue;

                for (unsigned int j = 0; j < mWidgets[i].size(); j++)
                {
                   w = mWidgets[i][j];
                   if (!w->getOverlayElement()->isVisible()) continue;
                   w->_cursorMoved(cursorPos);    // send event to widget
                }
             }

             if (mTrayDrag) return true;  // don't pass this event on if we're in the middle of a drag
             return false;
          }

        protected:

          /*-----------------------------------------------------------------------------
          | Internal method to prioritise / deprioritise expanded menus.
          -----------------------------------------------------------------------------*/
          void setExpandedMenu(SelectMenu* m)
          {
             if (!mExpandedMenu && m)
             {
                Ogre::OverlayContainer* c = (Ogre::OverlayContainer*)m->getOverlayElement();
                Ogre::OverlayContainer* eb = (Ogre::OverlayContainer*)c->getChild(m->getName() + "/MenuExpandedBox");
                eb->_update();
                eb->setPosition
                   ((unsigned int)(eb->_getDerivedLeft() * Ogre::OverlayManager::getSingleton().getViewportWidth()),
                   (unsigned int)(eb->_getDerivedTop() * Ogre::OverlayManager::getSingleton().getViewportHeight()));
                c->removeChild(eb->getName());
                mPriorityLayer->add2D(eb);
             }
             else if(mExpandedMenu && !m)
             {
                Ogre::OverlayContainer* eb = mPriorityLayer->getChild(mExpandedMenu->getName() + "/MenuExpandedBox");
                mPriorityLayer->remove2D(eb);
                ((Ogre::OverlayContainer*)mExpandedMenu->getOverlayElement())->addChild(eb);
             }

             mExpandedMenu = m;
          }

          Ogre::String mName;                   // name of this tray system
          Ogre::RenderWindow* mWindow;          // render window
    #if OGRE_PLATFORM == OGRE_PLATFORM_IPHONE
          OIS::MultiTouch* mMouse;              // multitouch device
    #else
          OIS::Mouse* mMouse;                   // mouse device
    #endif
          Ogre::Overlay* mBackdropLayer;        // backdrop layer
          Ogre::Overlay* mTraysLayer;           // widget layer
          Ogre::Overlay* mPriorityLayer;        // top priority layer
          Ogre::Overlay* mCursorLayer;          // cursor layer
          Ogre::OverlayContainer* mBackdrop;    // backdrop
          Ogre::OverlayContainer* mTrays[10];   // widget trays
           WidgetList mWidgets[10];              // widgets
          WidgetList mWidgetDeathRow;           // widget queue for deletion
          Ogre::OverlayContainer* mCursor;      // cursor
          SdkTrayListener* mListener;           // tray listener
          Ogre::Real mWidgetPadding;            // widget padding
          Ogre::Real mWidgetSpacing;            // widget spacing
          Ogre::Real mTrayPadding;              // tray padding
          bool mTrayDrag;                       // a mouse press was initiated on a tray
          SelectMenu* mExpandedMenu;            // top priority expanded menu widget
          TextBox* mDialog;                     // top priority dialog widget
          Ogre::OverlayContainer* mDialogShade; // top priority dialog shade
          Button* mOk;                          // top priority OK button
          Button* mYes;                         // top priority Yes button
          Button* mNo;                          // top priority No button
          bool mCursorWasVisible;               // cursor state before showing dialog
          Label* mFpsLabel;                     // FPS label
          ParamsPanel* mStatsPanel;             // frame stats panel
          DecorWidget* mLogo;                   // logo
          ProgressBar* mLoadBar;                // loading bar
          Ogre::Real mGroupInitProportion;      // proportion of load job assigned to initialising one resource group
          Ogre::Real mGroupLoadProportion;      // proportion of load job assigned to loading one resource group
          Ogre::Real mLoadInc;                  // loading increment
          Ogre::GuiHorizontalAlignment mTrayWidgetAlign[10];   // tray widget alignments
        };
    }

    #endif

i override this c++ code by c# (.net2.0)csharp snap code
    namespace Mogre_Procedural.MogreBites
    {
    using System;
    using Mogre;
    using System.Collections.Generic;
    using Math = System.Math;
    using InputContext = MOIS.Mouse;

    public enum TrayLocation : int // enumerator values for widget tray anchoring locations
    {
    TL_TOPLEFT,
    TL_TOP,
    TL_TOPRIGHT,
    TL_LEFT,
    TL_CENTER,
    TL_RIGHT,
    TL_BOTTOMLEFT,
    TL_BOTTOM,
    TL_BOTTOMRIGHT,
    TL_NONE
    }

    public enum ButtonState : int // enumerator values for button states
    {
    BS_UP,
    BS_OVER,
    BS_DOWN
    }



    // =============================================================================
    // | Listener class for responding to tray events.
    // =============================================================================
    public class SdkTrayListener
    {

    public virtual void Dispose() {
    }
    public virtual void buttonHit(Button button) {
    }
    public virtual void itemSelected(SelectMenu menu) {
    }
    public virtual void labelHit(Label label) {
    }
    public virtual void sliderMoved(Slider slider) {
    }
    public virtual void checkBoxToggled(CheckBox box) {
    }
    public virtual void okDialogClosed(string message) {
    }
    public virtual void yesNoDialogClosed(string question, bool yesHit) {
    }
    }
    ....
    public class FontDefault
    {
    public const string Default = "FONT.DEFAULT";
    public const string DefaultBold = "FONT.DEFAULT.BOLD";
    public const string Torchlight = "FONT.TORCHLIGHT";
    public const string Consolas = "FONT.CONSOLAS";
    public static void Load(string fontFileName, string fontRef, int size) {
    // Create the font resources
    //ResourceGroupManager.Singleton.AddResourceLocation("Media/fonts", "FileSystem");
    //Load("Default.ttf", Font.Default, 26);
    //Load("DefaultBold.ttf", Font.DefaultBold, 28);
    //Load("Torchlight.ttf", Font.Torchlight, 36);
    //Load("Consolas.ttf", Font.Consolas, 26);

    ResourcePtr font = FontManager.Singleton.Create(fontRef, ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME);
    font.SetParameter("type", "truetype");
    font.SetParameter("source", fontFileName);
    font.SetParameter("size", size.ToString());
    font.SetParameter("resolution", "96");
    font.Load();
    }
    }

    // =============================================================================
    // | Abstract base class for all widgets.
    // =============================================================================
    public class Widget : IDisposable
    {

    public Widget() {
    mTrayLoc = TrayLocation.TL_NONE;
    mElement = null;
    mListener = null;
    }
    /// <summary>
    /// dispose this widget
    /// </summary>
    public virtual void Dispose() {
    }

    public void cleanup() {
    if (mElement != null)
    nukeOverlayElement(mElement);
    mElement = null;
    }

    // -----------------------------------------------------------------------------
    // | Static utility method to recursively delete an overlay element plus
    // | all of its children from the system.
    // -----------------------------------------------------------------------------
    public static void nukeOverlayElement(OverlayElement element) {
    Mogre.OverlayContainer container = element as Mogre.OverlayContainer;
    if (container != null) {
    List<Mogre.OverlayElement> toDelete = new List<Mogre.OverlayElement>();

    Mogre.OverlayContainer.ChildIterator children = container.GetChildIterator();
    while (children.MoveNext()) {
    toDelete.Add(children.Current);
    }

    for (int i = 0; i < toDelete.Count; i++) {
    nukeOverlayElement(toDelete[i]);
    }
    }
    if (element != null) {
    Mogre.OverlayContainer parent = element.Parent;
    if (parent != null)
    parent.RemoveChild(element.Name);
    Mogre.OverlayManager.Singleton.DestroyOverlayElement(element);
    }
    }

    // -----------------------------------------------------------------------------
    // | Static utility method to check if the cursor is over an overlay element.
    // -----------------------------------------------------------------------------
    public static bool isCursorOver(Mogre.OverlayElement element, Mogre.Vector2 cursorPos) {
    return isCursorOver(element, cursorPos, 0f);
    }
    //C++ TO C# CONVERTER NOTE: Overloaded method(s) are created above to convert the following method having default parameters:
    //ORIGINAL LINE: static bool isCursorOver(Ogre::OverlayElement* element, const Ogre::Vector2& cursorPos, Ogre::Real voidBorder = 0)
    public static bool isCursorOver(Mogre.OverlayElement element, Mogre.Vector2 cursorPos, float voidBorder) {
    Mogre.OverlayManager om = Mogre.OverlayManager.Singleton;
    float l = element._getDerivedLeft() * om.ViewportWidth;
    float t = element._getDerivedTop() * om.ViewportHeight;
    float r = l + element.Width;
    float b = t + element.Height;

    return (cursorPos.x >= l + voidBorder && cursorPos.x <= r - voidBorder && cursorPos.y >= t + voidBorder && cursorPos.y <= b - voidBorder);
    }

    // -----------------------------------------------------------------------------
    // | Static utility method used to get the cursor's offset from the center
    // | of an overlay element in pixels.
    // -----------------------------------------------------------------------------
    public static Mogre.Vector2 cursorOffset(Mogre.OverlayElement element, Mogre.Vector2 cursorPos) {
    Mogre.OverlayManager om = Mogre.OverlayManager.Singleton;
    return new Mogre.Vector2(cursorPos.x - (element._getDerivedLeft() * om.ViewportWidth + element.Width / 2), cursorPos.y - (element._getDerivedTop() * om.ViewportHeight + element.Height / 2f));
    }
    //public static Vector2 cursorOffset(Mogre.OverlayContainer containerElement,Vector2 cursorPos)
    //{
    // Mogre.OverlayManager om = Mogre.OverlayManager.Singleton;
    // return new Mogre.Vector2(cursorPos.x - (containerElement._getDerivedLeft() * om.ViewportWidth + containerElement.Width / 2), cursorPos.y - (containerElement._getDerivedTop() * om.ViewportHeight + containerElement.Height / 2f));
    //}
    // -----------------------------------------------------------------------------
    // | Static utility method used to get the width of a caption in a text area.
    // -----------------------------------------------------------------------------
    public static float getCaptionWidth(string caption, ref Mogre.TextAreaOverlayElement area) {
    Mogre.FontPtr font = null;
    if (Mogre.FontManager.Singleton.ResourceExists(area.FontName)) {
    font = (Mogre.FontPtr)Mogre.FontManager.Singleton.GetByName(area.FontName);
    if (!font.IsLoaded) {
    font.Load();
    }
    }
    else {
    OGRE_EXCEPT("this font:", area.FontName, "is not exist");
    }
    //Font font = new Font(ft.Creator, ft.Name, ft.Handle, ft.Group, ft.IsManuallyLoaded);
    string current = DISPLAY_STRING_TO_STRING(caption);
    float lineWidth = 0f;

    for (int i = 0; i < current.Length; i++) {
    // be sure to provide a line width in the text area
    if (current[i] == ' ') {
    if (area.SpaceWidth != 0)
    lineWidth += area.SpaceWidth;
    else
    lineWidth += font.GetGlyphAspectRatio(' ') * area.CharHeight;
    }
    else if (current[i] == '
') break; // use glyph information to calculate line width else lineWidth += font.GetGlyphAspectRatio(current[i]) * area.CharHeight; } return (uint)lineWidth; } protected static void OGRE_EXCEPT(string p, string p_2, string p_3) { throw new Exception(p + "_" + p_2 + "_" + p_3); } protected static string DISPLAY_STRING_TO_STRING(string caption) { #if DISPLAY_STRING_TO_STRING_AlternateDefinition1 string current = (caption.asUTF8_c_str()); #elif DISPLAY_STRING_TO_STRING_AlternateDefinition2 string current = (caption.asUTF8()); #elif DISPLAY_STRING_TO_STRING_AlternateDefinition3 string current = (caption); #endif return caption; } // ----------------------------------------------------------------------------- // | Static utility method to cut off a string to fit in a text area. // ----------------------------------------------------------------------------- public static void fitCaptionToArea(string caption, ref Mogre.TextAreaOverlayElement area, float maxWidth) { Mogre.FontPtr font = null; if (Mogre.FontManager.Singleton.ResourceExists(area.FontName)) { font = (Mogre.FontPtr)Mogre.FontManager.Singleton.GetByName(area.FontName); if (!font.IsLoaded) { font.Load(); } } else { OGRE_EXCEPT("this font:", area.FontName, "is not exist"); } Mogre.FontPtr f = font; string s = DISPLAY_STRING_TO_STRING(caption); //int nl = s.find('
');
//if (nl != string.npos) // s = s.substr(0, nl); int nl = s.IndexOf('
'); if (nl != -1) s = s.Substring(0, nl); float width = 0; for (int i = 0; i < s.Length; i++) { if (s[i] == ' ' && area.SpaceWidth != 0) width += area.SpaceWidth; else width += f.GetGlyphAspectRatio(s[i]) * area.CharHeight; if (width > maxWidth) { s = s.Substring(0, i); break; } } area.Caption = (s); } public Mogre.OverlayElement getOverlayElement() { return mElement; } public string getName() { return mElement.Name; } public TrayLocation getTrayLocation() { return mTrayLoc; } public void hide() { mElement.Hide(); } public void show() { mElement.Show(); } public bool isVisible() { return mElement.IsVisible; } // callbacks public virtual void _cursorPressed(Mogre.Vector2 cursorPos) { } public virtual void _cursorReleased(Mogre.Vector2 cursorPos) { } public virtual void _cursorMoved(Mogre.Vector2 cursorPos) { } public virtual void _focusLost() { } // internal methods used by SdkTrayManager. do not call directly. public void _assignToTray(TrayLocation trayLoc) { mTrayLoc = trayLoc; } public void _assignListener(SdkTrayListener listener) { mListener = listener; } protected Mogre.OverlayElement mElement; protected TrayLocation mTrayLoc; protected SdkTrayListener mListener; } ....

the full code with c#,you can see: https://code.google.com/p/mogre-procedural/source/browse/trunk/Demo.MogreProcedural/SdkTrayUI/SdkTrayGUI.cs