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] == '\n') 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('\n'); //if (nl != string.npos) // s = s.substr(0, nl); int nl = s.IndexOf('\n'); 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