OGRE Wiki
Support and community documentation for Ogre3D
Ogre Forums
ogre3d.org
Log in
Username:
Password:
CapsLock is on.
Remember me (for 1 year)
Log in
Home
Tutorials
Tutorials Home
Basic Tutorials
Intermediate Tutorials
Mad Marx Tutorials
In Depth Tutorials
Older Tutorials
External Tutorials
Cookbook
Cookbook Home
CodeBank
Snippets
Experiences
Ogre Articles
Libraries
Libraries Home
Alternative Languages
Assembling A Toolset
Development Tools
OGRE Libraries
List of Libraries
Tools
Tools Home
DCC Tools
DCC Tutorials
DCC Articles
DCC Resources
Assembling a production pipeline
Development
Development Home
Roadmap
Building Ogre
Installing the Ogre SDK
Setting Up An Application
Ogre Wiki Tutorial Framework
Frequently Asked Questions
Google Summer Of Code
Help Requested
Ogre Core Articles
Community
Community Home
Projects Using Ogre
Recommended Reading
Contractors
Wiki
Immediate Wiki Tasklist
Wiki Ideas
Wiki Guidelines
Article Writing Guidelines
Wiki Styles
Wiki Page Tracker
Ogre Wiki Help
Ogre Wiki Help Overview
Help - Basic Syntax
Help - Images
Help - Pages and Structures
Help - Wiki Plugins
Toolbox
Freetags
Categories
List Pages
Structures
Trackers
Statistics
Rankings
List Galleries
Ogre Lexicon
Comments
History: MogreBetaGUI
View page
Source of version: 6
(current)
{img src="img/wiki_up/BetaGUI_example.png" alt="BetaGUI_example.png" imalign="right"} !!About MogreBetaGUI is a port of ((BetaGUI)). It's using overlays, therefore no external libraries are needed except Mogre itself. The BetaGUI is intended to be a very short example how to create a GUI. It is NOT intended to be a fully operational GUI supporting a lot of different controls and features. For a full GUI check out the ((Category:GUI|other GUI systems available)) for Mogre. __For questions etc. use [http://www.ogre3d.org/phpBB2addons/viewtopic.php?p=41143|this forum thread].__ The talk about the original Ogre add-on BetaGUI is [http://www.ogre3d.org/phpBB2/viewtopic.php?t=25853|in this thread]. {maketoc} !!Features * Creating a Window * Resizing the window via a bottom-right button. * Moving the window around via a top bar button. * Creating a push button in a window with a inactive and active material state. ** Calling back to a function or class to report when that button has been "pushed" * Creating a functional text gadget on a window to accept textual input to n characters. * Creating a static piece of text on a window. [http://www.nxogre.org/screens/betagui.avi|A video demonstrating the features] 1.26Mb, playable in VLC. !!Foreword of the porter Here's a couple of hours (and then some) work attempting to do a "direct" port of ((BetaGUI)) (v015) to Mogre. As it turned out, it's not 100% similar, but it's currently working for me with the following differences: * All OverlayElements are put inside an extra OverlayContainer; I just couldn't figure out how to do that particular casting trick with C#; this introduces foreach-loops when setting the (dis-)activated material for buttons, textinputs. If you're interested in fixing this, check out GUI.createOverlay. * Added a keyDelay timer, because it was handy for me. * Some extra checks for validity here and there (backspace handling). * I didn't need the type=1 callbacks, so they're left out for the moment; if your needs differ, look at C# delegates. * Maybe something else, but I've got a GUI now; using Mogre 0.2.0 & Visual Studio 2005 EE. Thanks again for Betajaen, his code is brilliant ^^ Usage instructions are as with the C++ version (((BetaGUI|here))), but see bottom of page. Cheers, funguine (forums) / ketarax (#ogre3d) [http://www.ogre3d.org/phpBB2/viewtopic.php?t=25853&postdays=0&postorder=asc&start=259|Original posting] !!Differences to ((BetaGUI|Ogre version)) * All OverlayElements are put inside an extra OverlayContainer; I just couldn't figure out how to do that particular casting trick with C#; this introduces foreach-loops when setting the (dis-)activated material for buttons, textinputs. If you're interested in fixing this, check out GUI.createOverlay. * Added a keyDelay timer. * Some extra checks for validity here and there (backspace handling). * No "type=1" callbacks, so they're left out for the moment; if your needs differ, look at C# delegates. !!Main source code The Mogre port is related to ((BetaGUI)) revision 015 (also called 1.0'15). {CODE(wrap="1", colors="c#")}/// Betajaen's GUI 015 Uncompressed /// Originally written by Robin "Betajaen" Southern 07-Nov-2006, http://www.ogre3d.org/wiki/index.php/BetaGUI /// This code is under the Whatevar! licence. Do what you want; but keep the original copyright header. /// This code is not meant to be readable, if you base your future source on this, I will laugh at you. using Mogre; using System; using System.Collections.Generic; namespace BetaGUI { enum wt { NONE = 0, MOVE = 1, RESIZE = 2, RESIZE_AND_MOVE = 3 }; public class GUI { public uint wc, bc, tc, oc; public Overlay mO, mMPo; public List<Window> WN = new List<Window>(); public Window mXW; public OverlayContainer mMP; public String mFont; public uint mFontSize; public Timer keyDelay = null; public GUI(String font, uint fontSize) { mXW = null; mMP = null; mFont = font; mFontSize = fontSize; wc = 0; bc = 0; tc = 0; oc = 0; mO = OverlayManager.Singleton.Create("BetaGUI"); mO.Show(); } public void hide() { for (int i = 0; i < WN.Count; i++) WN[i].hide(); mMP.Hide(); } public void show() { for (int i = 0; i < WN.Count; i++) WN[i].show(); if ( mMP != null) mMP.Show(); } public void killGUI() { for (int i = 0; i < WN.Count; i++) WN[i].killWindow(); WN.Clear(); mMP.Hide(); foreach (OverlayContainer container in mO.Get2DElementsIterator()) { foreach (OverlayElement element in container.GetChildIterator()) OverlayManager.Singleton.DestroyOverlayElement(element); mO.Remove2D(container); OverlayManager.Singleton.DestroyOverlayElement(container); } OverlayManager.Singleton.Destroy(mO); foreach ( OverlayContainer container in mMPo.Get2DElementsIterator()) { foreach (OverlayElement element in container.GetChildIterator()) OverlayManager.Singleton.DestroyOverlayElement(element); mMPo.Remove2D(container); OverlayManager.Singleton.DestroyOverlayElement(container); } OverlayManager.Singleton.Destroy(mMPo); mMP = null; if (keyDelay != null) keyDelay.Dispose(); } public bool injectMouse(uint x, uint y, bool LMB) { if (mMP != null) mMP.SetPosition(x, y); if (mXW != null) { int i = 0; foreach (Window win in WN) { if (mXW == win) { mXW.killWindow(); WN.RemoveAt(i); return false; } i++; } } for (int i = 0; i < WN.Count; i++) { if (WN[i].check(x,y, LMB)) { return true; } } return false; } public bool injectKey(String key, uint x, uint y) { if (keyDelay == null) keyDelay = new Timer(); if (keyDelay.Milliseconds > 150) { for (int i = 0; i < WN.Count; i++) { if (WN[i].checkKey(key, x, y)) return true; } } return false; } public void injectBackspace(uint x, uint y) { injectKey("!b", x, y); } public Window createWindow(Vector4 D, String M, int T, String C) { Window w = new Window(D, M, T, C, this); WN.Add(w); return w; } public void destroyWindow(Window w) { mXW = w; } public OverlayContainer createOverlay(String N, Vector2 P, Vector2 D, String M, String C, bool A) { String t = "Panel"; if (C != "") t = "TextArea"; OverlayElement e = OverlayManager.Singleton.CreateOverlayElement(t, N); e.MetricsMode = GuiMetricsMode.GMM_PIXELS; e.SetDimensions(D.x, D.y); e.SetPosition(0, 0); //if (M != "") // e.MaterialName = M; if (C != "") { e.Caption = C; e.SetParameter("font_name", mFont); e.SetParameter("char_height", StringConverter.ToString(mFontSize)); } OverlayContainer c = (OverlayContainer)OverlayManager.Singleton.CreateOverlayElement("Panel", "ContainerHack" + (oc++).ToString()); c.MetricsMode = GuiMetricsMode.GMM_PIXELS; c.SetDimensions(D.x, D.y); c.SetPosition(P.x, P.y); if (M != "") c.MaterialName = M; c.AddChild(e); if (A) { mO.Add2D(c); c.Show(); } return c; } public OverlayContainer createMousePointer(Vector2 d, String m) { mMPo = OverlayManager.Singleton.Create("BetaGUI.MP"); mMPo.ZOrder = 649; mMP = createOverlay("bg.mp", new Vector2(0, 0), d, m, "", false); mMPo.Add2D(mMP); mMPo.Show(); mMP.Show(); return mMP; } } // class GUI public class Button { public OverlayContainer mO, mCP; public String mmn, mma; public Callback callback; public uint x, y, w, h; public Button(Vector4 D, String M, String T, Callback C, Window P) { x = (uint)D.x; y = (uint)D.y; w = (uint)D.z; h = (uint)D.w; mmn = M; mma = M; ResourcePtr ma = MaterialManager.Singleton.GetByName(mmn + ".active"); if (ma != null) { mma += ".active"; } mO = P.mGUI.createOverlay(P.mO.Name + "b" + StringConverter.ToString(P.mGUI.bc++), new Vector2(x, y), new Vector2(w, h), M, "", false); mCP = P.mGUI.createOverlay(mO.Name + "c", new Vector2(4, (h - P.mGUI.mFontSize) / 2), new Vector2(w, h), "", T, false); P.mO.AddChild(mO); mO.Show(); mO.AddChild(mCP); mCP.Show(); callback = C; } public void killButton() { foreach (OverlayContainer container in mO.GetChildContainerIterator()) foreach (OverlayElement element in container.GetChildIterator()) OverlayManager.Singleton.DestroyOverlayElement(element); foreach (OverlayElement element in mO.GetChildIterator()) OverlayManager.Singleton.DestroyOverlayElement(element); mO.Parent.RemoveChild(mO.Name); OverlayManager.Singleton.DestroyOverlayElement(mO); } public void activate(bool a) { if (!a && mmn != "") mO.MaterialName = mmn; if (a && mma != "") mO.MaterialName = mma; } public bool isin(uint mx, uint my, uint px, uint py) { return (!(mx >= x + px && my >= y + py)) || (!(mx <= x + px + w && my <= y + py + h)); } } public class TextInput { public OverlayContainer mO, mCP; public String mmn, mma, value; public uint x, y, w, h, length; public String getValue() { return value; } public void setValue(String v) { mO.Caption = value = v; } // mCP here if ... public TextInput(Vector4 D, String M, String V, uint L, Window P) { x = (uint)D.x; y = (uint)D.y; w = (uint)D.z; h = (uint)D.w; value = V; mmn = M; mma = M; length = L; ResourcePtr ma = MaterialManager.Singleton.GetByName(mmn + ".active"); if ( ma != null) mma += ".active"; mO = P.mGUI.createOverlay(P.mO.Name + "t" + StringConverter.ToString(P.mGUI.tc++), new Vector2(x, y), new Vector2(w, h), M, "", false); mCP = P.mGUI.createOverlay(mO.Name + "c", new Vector2(0, (h - P.mGUI.mFontSize) / 2), new Vector2(w, h), "", V, false); P.mO.AddChild(mO); mO.Show(); mO.AddChild(mCP); mCP.Show(); } public void killTextInput() { foreach (OverlayContainer container in mO.GetChildContainerIterator()) foreach (OverlayElement element in container.GetChildIterator()) OverlayManager.Singleton.DestroyOverlayElement(element); foreach (OverlayElement element in mO.GetChildIterator()) OverlayManager.Singleton.DestroyOverlayElement(element); mO.Parent.RemoveChild(mO.Name); OverlayManager.Singleton.DestroyOverlayElement(mO); } public void activate(bool a) { if (!a && mmn != "") mO.MaterialName = mmn; if (a && mma != "") mO.MaterialName = mma; } public bool isin(uint mx, uint my, uint px, uint py) { return (!(mx >= x + px && my >= y + py)) || (!(mx <= x + px + w && my <= y + py + h)); } } public class Window { public TextInput mATI; public Button mRZ, mAB, mTB; // resize, activebutton, titlebar public uint x, y, w, h; public GUI mGUI; public OverlayContainer mO; public List<Button> mB = new List<Button>(); public List<TextInput> mT = new List<TextInput>(); public Button createButton(Vector4 D, String M, String T, Callback C) { Button x = new Button(D, M, T, C, this); mB.Add(x); return x; } public TextInput createTextInput(Vector4 D, String M, String V, uint L) { TextInput x = new TextInput(D, M, V, L, this); mT.Add(x); return x; } public void createStaticText(Vector4 D, String T) { OverlayContainer x = mGUI.createOverlay(mO.Name + StringConverter.ToString(mGUI.tc++), new Vector2(D.x, D.y), new Vector2(D.z, D.w), "", T, false); mO.AddChild(x); x.Show(); } public void hide() { mO.Hide(); } public void show() { mO.Show(); } public bool isVisible() { return mO.IsVisible; } public Window(Vector4 D, String M, int t, String C, GUI G) { x = (uint) D.x; y = (uint) D.y; w = (uint) D.z; h = (uint) D.w; mGUI = G; mTB = null; mRZ = null; mATI = null; mAB = null; mO = G.createOverlay("BetaGUI.w" + StringConverter.ToString(G.wc++), new Vector2(D.x, D.y), new Vector2(D.z, D.w), M, C, true); if (t >= 2) { Callback c = new Callback(); c.t = 4; mRZ = createButton(new Vector4(D.z - 16, D.w - 16, 16, 16), M + ".resize", "", c); } if (t == 1 || t == 3) { Callback c = new Callback(); c.t = 3; mTB = createButton(new Vector4(0, 0, D.z, 22), M + ".titlebar", C, c); } } public void killWindow() { for (int i = 0; i < mB.Count; i++) mB[i].killButton(); for (int i = 0; i < mT.Count; i++) mT[i].killTextInput(); } public bool check(uint px, uint py, bool LMB) { if (!mO.IsVisible) return false; if (!(px >= x && py >= y) || !(px <= x + w && py <= y + h)) { if (mAB != null) mAB.activate(false); return false; } if (mAB != null) mAB.activate(false); for (int i = 0; i < mB.Count; i++) { if (mB[i].isin(px, py, x, y)) continue; if (mAB != null ) mAB.activate(false); mAB = mB[i]; mAB.activate(true); if (mATI != null) { mATI.activate(false); mATI = null; } if (!LMB) return true; switch (mAB.callback.t) { default: return true; case 1: //mAB.callback.fp(mAB); // FIX / what is this return true; case 2: mAB.callback.LS.onButtonPress(mAB); return true; case 3: mO.SetPosition(x = px - (mAB.w / 2), y = py - (mAB.h / 2)); return true; case 4: mO.SetDimensions(w = px - x + 8, h = py - y + 8); mRZ.mO.SetPosition(mRZ.x = w - 16, mRZ.y = h - 16); if (mTB != null) { mTB.mO.Width = mTB.w = w; } return true; } } if (!LMB) return true; for (int i = 0; i < mT.Count; i++) { if (mT[i].isin(px, py, x, y)) continue; mATI = mT[i]; mATI.activate(true); return true; } if (mATI != null) { mATI.activate(false); mATI = null; } return true; } public bool checkKey(String k, uint px, uint py) { if (mATI == null) return false; if (!mO.IsVisible) return false; if (!(px >= x && py >= y) || !(px <= x + w && py <= y + h)) return false; if (k == "!b" && mATI.value.Length > 0) { mATI.setValue(mATI.value.Substring(0, mATI.value.Length - 1)); foreach (OverlayElement element in mATI.mCP.GetChildIterator()) element.Caption = mATI.value; mGUI.keyDelay.Reset(); return true; } if (mATI.value.Length >= mATI.length) return true; if ( k != "!b") mATI.value += k; foreach ( OverlayElement element in mATI.mCP.GetChildIterator() ) // take from mCP if ... element.Caption = mATI.value; mGUI.keyDelay.Reset(); return true; } } public interface BetaGUIListener { void onButtonPress(Button referer); } public class Callback { public uint t; public BetaGUIListener LS; public Callback() { t=0; } public Callback (BetaGUIListener L) { t=2; LS=L; } } }{CODE} !!Usage * Add a link to the ''MOIS.dll'' library (see ((MOIS))) * Add the ((BetaGUI|#Betajaen.27s GUI Resources|Betajaen's GUI Resources)) * Add '' :BetaGUIListener'' inheritence to your Scene() class definition Here's the creation of a simple user interface: {CODE(wrap="1", colors="c#")}Button single; Button lanmulti; Button netmulti; GUI mGui = new GUI("StarWars", 24); mGui.createMousePointer(new Vector2(30, 30), "bgui.pointer"); BetaGUI.Window window = mGui.createWindow(new Vector4(viewport.ActualWidth/4, viewport.ActualHeight/4, viewport.ActualWidth/2, viewport.ActualHeight/2), "bgui.window", (int)BetaGUI.wt.RESIZE_AND_MOVE, "Select game mode"); Callback cc = new Callback(this); // remember to give your program the BetaGUIListener interface single = window.createButton(new Vector4(0, 30, viewport.ActualWidth/2, 30), "bgui.button", "Single Player", cc); lanmulti = window.createButton(new Vector4(0, 60, viewport.ActualWidth/2, 30), "bgui.button", "LAN Multiplay", cc); netmulti = window.createButton(new Vector4(0, 90, viewport.ActualWidth/2, 30), "bgui.button", "Internet Multiplay", cc); window.createTextInput(new Vector4(0, 120, viewport.ActualWidth / 2, 30), "bgui.textinput", "testing", 20); window.show();{CODE} Then the BetaGUIListener callback (the buttons single, lanmulti and netmulti as well as mGui are globally accessible): The enumeration PlayMode doesn't really exist, it's just for demonstration purposes. {CODE(wrap="1", colors="c#")}public void onButtonPress(Button butt) { if (butt == single) { Console.WriteLine("Play solo!"); } else if (butt == lanmulti) { Console.WriteLine("Play in LAN!"); } else if (butt == netmulti) { Console.WriteLine("Play in Internet!"); } else { Console.WriteLine("*Some* button was pressed!"); } mGui.hide(); }{CODE} And an amazingly crude delivery of user input to the gui; I do this in frameStarted(): __Note:__ This is just an example, you have to implement your own keycodes to support more keys. {CODE(wrap="1", colors="c#")}if (mGui != null) { MOIS.MouseState_NativePtr mouseState = inputMouse.MouseState; uint screenx = (uint)(viewport.ActualWidth * ((float)mouseState.X.abs / 50f)); uint screeny = (uint)(viewport.ActualHeight * ((float)mouseState.Y.abs / 50f)); if (inputKeyboard.IsKeyDown(MOIS.KeyCode.KC_BACK)) { //mGui.injectBackspace(screenx, screeny); mGui.injectKey("!b", screenx, screeny); } if (inputKeyboard.IsKeyDown(MOIS.KeyCode.KC_1)) { mGui.injectKey("1", screenx, screeny); } if (mouseState.ButtonDown(MOIS.MouseButtonID.MB_Left)) { mGui.injectMouse(screenx, screeny, true); } else { mGui.injectMouse(screenx, screeny, false); } }{CODE} !!Documentation? ''No class member is documented and many names are cryptical at the moment.'' ''It would be great, if someone could add XML descriptions to important members! '' ''Maybe also rename variable / method / attribute names? '' ''On changing the code please tell it in wiki log.'' !!See also * ((BetaGUI)) * ((MOIS)) (key and mouse interaction) * ((MQuickGUI)) (an other GUI system for Mogre) * ((Mogre CEGUI)) * [http://www.ogre3d.org/phpBB2addons/viewtopic.php?p=36826#36826|Overlays] (the basic 2D elements in Ogre) * Source code to extend MogreBetaGUI with [http://www.ogre3d.org/phpBB2addons/viewtopic.php?p=47533#47531|alterable overlays]
Search by Tags
Search Wiki by Freetags
Latest Changes
One Function Ogre
IDE Eclipse
FMOD SoundManager
HDRlib
Building Ogre V2 with CMake
Ogre 2.1 FAQ
Minimal Ogre Collision
Artifex Terra
OpenMB
Advanced Mogre Framework
...more
Search
Find
Advanced
Search Help
Online Users
364 online users