|
|
(4 intermediate revisions not shown) |
Line 14: |
Line 14: |
| <br>http://www.cegui.org.uk/gallery/albums/userpics/10001/4.jpg | | <br>http://www.cegui.org.uk/gallery/albums/userpics/10001/4.jpg |
| <br>CEGUI is the default GUI framework under OGRE. I had considerable problems getting it to work, though it was reasonably simple once everything was described (a situation of files all over the place without a meaningfuil structure in OGRE - would need some cleaning up). Also, the available support and guides are scarce. It is also rather clumsy to initialise, if perhaps not to work with. | | <br>CEGUI is the default GUI framework under OGRE. I had considerable problems getting it to work, though it was reasonably simple once everything was described (a situation of files all over the place without a meaningfuil structure in OGRE - would need some cleaning up). Also, the available support and guides are scarce. It is also rather clumsy to initialise, if perhaps not to work with. |
- | * It seems the most powerful GUI library by far.
| + | |
| * It has bindings for Irrlicht and OpenSceneGraph so it might be considered a relatively inter-API-portable framework. | | * It has bindings for Irrlicht and OpenSceneGraph so it might be considered a relatively inter-API-portable framework. |
- | <pre style="margin:1em; background:black;color:lightgray; size:small;">
| + | * CEGUI is very oriented toward defining widgets in XML files. Changing widgets programmatically is done by setting their properties through a messaging system. This message system is clunky and poorly documented. |
- | /************************************************************************/
| + | * The CEGUI documentation (both Wiki and source-generated API documentation) is insufficient, terse and often unhelpful. |
- | /* EVALUATION OF CEGUI */
| + | * CEGUI is by far the most powerful GUI library with the most supported widgets. |
- | /* */
| + | |
- | /* > Includes are in OGRE_HOME/Samples, which must be added to paths(!) */
| + | |
- | /* */
| + | |
- | /************************************************************************/
| + | |
- | | + | |
- | #include "../source/wartbed/Wartbed.h"
| + | |
- | | + | |
- | #include <CEGUI/CEGUI.h>
| + | |
- | #include <CEGUI/CEGUIDefaultResourceProvider.h>
| + | |
- | #include <OgreCEGUIRenderer.h>
| + | |
- | | + | |
- | | + | |
- | CEGUI::System *g_pSystem = 0;
| + | |
- | CEGUI::OgreCEGUIRenderer *g_pRenderer = 0; | + | |
- | CEGUI::WindowManager *g_pWinMngr = 0;
| + | |
- | CEGUI::Window *g_pSheet = 0;
| + | |
- | CEGUI::Window *g_pButton = 0;
| + | |
- | | + | |
- | | + | |
- | struct FrameListener : wb::FrameListener
| + | |
- | {
| + | |
- | bool frameStarted(const Ogre::FrameEvent& evt)
| + | |
- | {
| + | |
- | using namespace wb::ogre;
| + | |
- | | + | |
- | if (pKeyboard->isKeyDown(OIS::KC_ESCAPE))
| + | |
- | {
| + | |
- | Stop();
| + | |
- | return false;
| + | |
- | }
| + | |
- | | + | |
- | else
| + | |
- | wb::FrameListener::frameStarted( evt );
| + | |
- | }
| + | |
- | };
| + | |
- | | + | |
- | | + | |
- | struct KeyListener : wb::KeyListener
| + | |
- | {
| + | |
- | bool keyPressed( OIS::KeyEvent const &e )
| + | |
- | {
| + | |
- | g_pSystem->injectKeyDown( e.key );
| + | |
- | g_pSystem->injectChar( e.text );
| + | |
- | return true;
| + | |
- | }
| + | |
- | | + | |
- | bool keyReleased( OIS::KeyEvent const &e )
| + | |
- | {
| + | |
- | g_pSystem->injectKeyUp( e.key );
| + | |
- | return true;
| + | |
- | }
| + | |
- | };
| + | |
- | | + | |
- | | + | |
- | struct MouseListener : wb::MouseListener
| + | |
- | {
| + | |
- | CEGUI::MouseButton convert( OIS::MouseButtonID buttonID )
| + | |
- | {
| + | |
- | switch (buttonID)
| + | |
- | {
| + | |
- | case OIS::MB_Left: return CEGUI::LeftButton;
| + | |
- | case OIS::MB_Right: return CEGUI::RightButton;
| + | |
- | case OIS::MB_Middle: return CEGUI::MiddleButton;
| + | |
- | default: return CEGUI::LeftButton;
| + | |
- | }
| + | |
- | }
| + | |
- | | + | |
- | bool mouseMoved( OIS::MouseEvent const &e )
| + | |
- | {
| + | |
- | g_pSystem->injectMouseMove( e.state.X.rel, e.state.Y.rel );
| + | |
- | | + | |
- | if(e.state.Z.rel != 0)
| + | |
- | g_pSystem->injectMouseWheelChange( e.state.Z.rel );
| + | |
- | | + | |
- | return true;
| + | |
- | }
| + | |
- | | + | |
- | bool mousePressed( OIS::MouseEvent const &e, OIS::MouseButtonID id )
| + | |
- | {
| + | |
- | g_pSystem->injectMouseButtonDown( convert(id) );
| + | |
- | return true;
| + | |
- | }
| + | |
- | | + | |
- | bool mouseReleased( OIS::MouseEvent const &e, OIS::MouseButtonID id )
| + | |
- | {
| + | |
- | g_pSystem->injectMouseButtonUp( convert(id) );
| + | |
- | return true;
| + | |
- | }
| + | |
- | };
| + | |
- | | + | |
- | | + | |
- | bool OnClick( CEGUI::EventArgs const &args )
| + | |
- | {
| + | |
- | MessageBeep( MB_OK );
| + | |
- | return true;
| + | |
- | }
| + | |
- | | + | |
- | | + | |
- | | + | |
- | //=============================================================================
| + | |
- | // Main function...
| + | |
- | //
| + | |
- | //-----------------------------------------------------------------------------
| + | |
- | | + | |
- | std::string app_name;
| + | |
- | std::string app_path;
| + | |
- | | + | |
- | #if OGRE_PLATFORM == PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WIN32
| + | |
- | | + | |
- | //---------------------------------------------------------------------
| + | |
- | // Windows main signature
| + | |
- | //---------------------------------------------------------------------
| + | |
- | | + | |
- | #define WIN32_LEAN_AND_MEAN
| + | |
- | #include "windows.h"
| + | |
- | | + | |
- | INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
| + | |
- | {
| + | |
- | app_name.resize( _MAX_PATH );
| + | |
- | GetModuleFileNameA( NULL, &app_name[0], _MAX_PATH );
| + | |
- | | + | |
- | STARTUPINFO startupInfo;
| + | |
- | GetStartupInfo( &startupInfo );
| + | |
- | | + | |
- | | + | |
- | #else
| + | |
- | | + | |
- | //---------------------------------------------------------------------
| + | |
- | // POSIX main signature
| + | |
- | //---------------------------------------------------------------------
| + | |
- | | + | |
- | int main(int argc, char **argv)
| + | |
- | {
| + | |
- | app_name = argv[0];
| + | |
- | | + | |
- | #endif
| + | |
- | | + | |
- | | + | |
- | utils::tokeniser<char> t( app_name, "\\" );
| + | |
- | app_path = t.collate( 0, t.size()-3, "/" );
| + | |
- | | + | |
- | //---------------------------------------------------------------------
| + | |
- | // Common main body
| + | |
- | //---------------------------------------------------------------------
| + | |
- | | + | |
- | // The entire game is initialised, started and run in the FCom()
| + | |
- | // function.
| + | |
- | //
| + | |
- | try
| + | |
- | {
| + | |
- | Wartbed::getInstance( "CEGUI Test" ).setFrameListener( new FrameListener );
| + | |
- | Wartbed::getInstance().setKeyListener( new KeyListener );
| + | |
- | Wartbed::getInstance().setMouseListener( new MouseListener );
| + | |
- | | + | |
- | Ogre::ResourceGroupManager::getSingleton().addResourceLocation( "./Fonts", "FileSystem" );
| + | |
- | Ogre::ResourceGroupManager::getSingleton().addResourceLocation( "./CEGUI", "FileSystem" );
| + | |
- | | + | |
- | // Instruct Ogre to go through all paths set by addResourceLocation
| + | |
- | // and add any comptible resources.
| + | |
- | //
| + | |
- | Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
| + | |
- | | + | |
- | using namespace wb::ogre;
| + | |
- | | + | |
- | g_pRenderer = new CEGUI::OgreCEGUIRenderer( pWindow, Ogre::RENDER_QUEUE_OVERLAY, false, 3000, pSceneManager );
| + | |
- | g_pSystem = new CEGUI::System( g_pRenderer );
| + | |
- | | + | |
- | | + | |
- | // initialise the required dirs for the DefaultResourceProvider
| + | |
- | CEGUI::DefaultResourceProvider *rp =
| + | |
- | static_cast<CEGUI::DefaultResourceProvider *>
| + | |
- | (CEGUI::System::getSingleton().getResourceProvider());
| + | |
- | | + | |
- | | + | |
- | // Load GUI styles
| + | |
- | //
| + | |
- | CEGUI::SchemeManager::getSingleton().loadScheme( (CEGUI::utf8 *) "TaharezLookSkin.scheme" );
| + | |
- | g_pSystem->setDefaultMouseCursor( (CEGUI::utf8*)"TaharezLook", (CEGUI::utf8 *) "MouseArrow" );
| + | |
- | g_pSystem->setDefaultFont( (CEGUI::utf8 *) "BlueHighway-12" );
| + | |
- | | + | |
- | // Create a sheet to work on
| + | |
- | //
| + | |
- | g_pWinMngr = CEGUI::WindowManager::getSingletonPtr();
| + | |
- | g_pSheet = g_pWinMngr->createWindow( "DefaultGUISheet", "CEGUIDemo/Sheet" );
| + | |
- | g_pButton = g_pWinMngr->createWindow( "TaharezLook/Button", "CEGUIDemo/QuitButton" );
| + | |
- | | + | |
- | // Create and activate a clickable button
| + | |
- | //
| + | |
- | g_pButton->setText( "Click me" );
| + | |
- | g_pButton->setPosition( CEGUI::UVector2(CEGUI::UDim(0, 10), CEGUI::UDim(0, 5)) );
| + | |
- | g_pButton->setSize( CEGUI::UVector2(CEGUI::UDim(0.15, 0), CEGUI::UDim(0.05, 0)) );
| + | |
- | g_pSheet->addChildWindow( g_pButton );
| + | |
- | g_pSystem->setGUISheet( g_pSheet );
| + | |
- | | + | |
- | g_pButton->subscribeEvent
| + | |
- | (
| + | |
- | CEGUI::PushButton::EventClicked,
| + | |
- | CEGUI::Event::Subscriber( &OnClick )
| + | |
- | );
| + | |
- | | + | |
- | // Show the mouse using the default mouse cursor image
| + | |
- | //
| + | |
- | CEGUI::MouseCursor::getSingleton().setImage( g_pSystem->getDefaultMouseCursor() );
| + | |
- | | + | |
- | | + | |
- | Wartbed::getInstance().mainLoop();
| + | |
- | }
| + | |
- | | + | |
- | | + | |
- | //---------------------------------------------------------------------
| + | |
- | // Last-ditch exception handling
| + | |
- | //---------------------------------------------------------------------
| + | |
- | | + | |
- | catch (Ogre::Exception &e)
| + | |
- | {
| + | |
- | #if OGRE_PLATFORM == PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WIN32
| + | |
- | MessageBoxA( NULL, e.what(), "An exception has occurred!", MB_OK | MB_ICONERROR | MB_TASKMODAL );
| + | |
- | #else
| + | |
- | stderr << "An exception has occurred: " << e.what() << std::endl;
| + | |
- | #endif
| + | |
- | }
| + | |
- | | + | |
- | | + | |
- | catch (std::exception &e)
| + | |
- | {
| + | |
- | #if OGRE_PLATFORM == PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WIN32
| + | |
- | MessageBoxA( NULL, e.what(), "An exception has occurred!", MB_OK | MB_ICONERROR | MB_TASKMODAL );
| + | |
- | #else
| + | |
- | stderr << "An exception has occurred: " << e.what() << std::endl;
| + | |
- | #endif
| + | |
- | }
| + | |
- | | + | |
- | | + | |
- | catch (...)
| + | |
- | {
| + | |
- | #if OGRE_PLATFORM == PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WIN32
| + | |
- | MessageBoxA( NULL, "Unknows exception thrown!", "An exception has occurred!", MB_OK | MB_ICONERROR | MB_TASKMODAL );
| + | |
- | #else
| + | |
- | stderr << "An exception has occurred: " << e.what() << std::endl;
| + | |
- | #endif
| + | |
- | }
| + | |
- | | + | |
- | | + | |
- | return EXIT_SUCCESS;
| + | |
- | }
| + | |
- | | + | |
- | //-----------------------------------------------------------------------------
| + | |
- | //
| + | |
- | // ...end main function
| + | |
- | //=============================================================================
| + | |
- | </pre>
| + | |
| | | |
| ===QuickGUI=== | | ===QuickGUI=== |
| http://www.ogre3d.org/wiki/index.php/QuickGUI | | http://www.ogre3d.org/wiki/index.php/QuickGUI |
| <br>http://stormsonggames.com/downloads/images/OgreForum/qgui_9_3.jpg | | <br>http://stormsonggames.com/downloads/images/OgreForum/qgui_9_3.jpg |
- | <br>Made for OGRE, inspired by BetGUI and CEGUI. It seems reasonably complete and is the framework I've gotten furthest with so far. | + | <br>Made for OGRE, inspired by BetGUI and CEGUI. |
- | <pre style="margin:1em; background:black;color:lightgray; size:small;">
| + | |
- | /************************************************************************/
| + | |
- | /* EVALUATION OF QuickGUI */
| + | |
- | /* */
| + | |
- | /* */
| + | |
- | /************************************************************************/
| + | |
| | | |
- | #include "../source/wartbed/Wartbed.h"
| + | * QuickGUI has somewhat overly complicated initial set-up syntax requirements. |
- | #include <QuickGUI.h>
| + | * QuickGUI is quite easy to work with and neither terse not verbose |
- | | + | * Widgets are widgets and communicated with through methods, not messages. This is object-oriented but also may entail plenty of casting depending on coding style. |
- | | + | * The widgets are more limited in automagic functionality than CEGUI (f.i. no 4-state button widget) but are easy to work with programatically on events. |
- | #pragma comment(lib, "D:/( C++ )/QuickGUI_9_03/bin/QuickGUI_d.lib")
| + | * QuickGUI seems not to support ImageSet-like bitmap abstractions, wherefore all icons must be in unique files? |
- | | + | * QuickGUI has virtually no documentation. |
- | | + | * There are quirks: events must be methods in a class rather than free functions. The even handler class must be polymorphic (at least one virtual method) dur to internal dynamic_casts under the QuickGUI hood. QuickGUI seems less mature and robustly written than CEGUI. |
- | QuickGUI::GUIManager *g_pGUIManager = 0;
| + | |
- | QuickGUI::Sheet *g_pSheet = 0; | + | |
- | QuickGUI::Button *g_pButton = 0;
| + | |
- | | + | |
- | | + | |
- | struct FrameListener : wb::FrameListener
| + | |
- | {
| + | |
- | bool frameStarted(const Ogre::FrameEvent& evt)
| + | |
- | {
| + | |
- | using namespace wb::ogre;
| + | |
- | | + | |
- | if (pKeyboard->isKeyDown(OIS::KC_ESCAPE))
| + | |
- | {
| + | |
- | Stop();
| + | |
- | return false;
| + | |
- | }
| + | |
- | | + | |
- | else
| + | |
- | wb::FrameListener::frameStarted( evt );
| + | |
- | }
| + | |
- | };
| + | |
- | | + | |
- | | + | |
- | struct KeyListener : wb::KeyListener
| + | |
- | {
| + | |
- | bool keyPressed(const OIS::KeyEvent& e)
| + | |
- | {
| + | |
- | g_pGUIManager->injectChar( static_cast<Ogre::UTFString::unicode_char>(e.text) );
| + | |
- | g_pGUIManager->injectKeyDown( static_cast<QuickGUI::KeyCode>(e.key) );
| + | |
- | return true;
| + | |
- | }
| + | |
- | | + | |
- | bool keyReleased(const OIS::KeyEvent& e)
| + | |
- | {
| + | |
- | g_pGUIManager->injectKeyUp( static_cast<QuickGUI::KeyCode>(e.key) );
| + | |
- | return true;
| + | |
- | }
| + | |
- | };
| + | |
- | | + | |
- | | + | |
- | struct MouseListener : wb::MouseListener
| + | |
- | {
| + | |
- | bool mouseMoved( OIS::MouseEvent const &e )
| + | |
- | {
| + | |
- | g_pGUIManager->injectMousePosition( e.state.X.abs, e.state.Y.abs );
| + | |
- | | + | |
- | if(e.state.Z.rel != 0)
| + | |
- | g_pGUIManager->injectMouseWheelChange( e.state.Z.rel );
| + | |
- | | + | |
- | return true;
| + | |
- | }
| + | |
- | | + | |
- | bool mousePressed( OIS::MouseEvent const &e, OIS::MouseButtonID id)
| + | |
- | {
| + | |
- | g_pGUIManager->injectMouseButtonDown( static_cast<QuickGUI::MouseButtonID>(id) );
| + | |
- | return true;
| + | |
- | }
| + | |
- | | + | |
- | bool mouseReleased( OIS::MouseEvent const &e, OIS::MouseButtonID id)
| + | |
- | {
| + | |
- | g_pGUIManager->injectMouseButtonUp( static_cast<QuickGUI::MouseButtonID>(id) );
| + | |
- | return true;
| + | |
- | }
| + | |
- | };
| + | |
- | | + | |
- | | + | |
- | struct GUIEventHandler
| + | |
- | {
| + | |
- | GUIEventHandler()
| + | |
- | {
| + | |
- | g_pButton->addWidgetEventHandler
| + | |
- | (
| + | |
- | QuickGUI::WIDGET_EVENT_MOUSE_BUTTON_UP,
| + | |
- | &GUIEventHandler::onClick,
| + | |
- | this
| + | |
- | );
| + | |
- | }
| + | |
- | | + | |
- | // Note that this must be declared virtual because QuickGUI required a
| + | |
- | // polymorphic class or its dynamic_cast calls will throw
| + | |
- | //
| + | |
- | virtual ~GUIEventHandler() {}
| + | |
- | | + | |
- | void onClick( QuickGUI::EventArgs const &args)
| + | |
- | {
| + | |
- | QuickGUI::MouseEventArgs const &mea =
| + | |
- | static_cast<const QuickGUI::MouseEventArgs &>( args );
| + | |
- | | + | |
- | if (mea.button == QuickGUI::MB_Left)
| + | |
- | {
| + | |
- | MessageBeep( MB_OK );
| + | |
- | }
| + | |
- | | + | |
- | if (mea.button == QuickGUI::MB_Right)
| + | |
- | {
| + | |
- | MessageBeep( MB_ICONEXCLAMATION );
| + | |
- | }
| + | |
- | }
| + | |
- | };
| + | |
- | | + | |
- | | + | |
- | //=============================================================================
| + | |
- | // Main function...
| + | |
- | //
| + | |
- | //-----------------------------------------------------------------------------
| + | |
- | | + | |
- | std::string app_name;
| + | |
- | std::string app_path;
| + | |
- | | + | |
- | #if OGRE_PLATFORM == PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WIN32
| + | |
- | | + | |
- | //---------------------------------------------------------------------
| + | |
- | // Windows main signature
| + | |
- | //---------------------------------------------------------------------
| + | |
- | | + | |
- | #define WIN32_LEAN_AND_MEAN
| + | |
- | #include "windows.h"
| + | |
- | | + | |
- | INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
| + | |
- | {
| + | |
- | app_name.resize( _MAX_PATH );
| + | |
- | GetModuleFileNameA( NULL, &app_name[0], _MAX_PATH );
| + | |
- | | + | |
- | STARTUPINFO startupInfo;
| + | |
- | GetStartupInfo( &startupInfo );
| + | |
- | | + | |
- | | + | |
- | #else
| + | |
- | | + | |
- | //---------------------------------------------------------------------
| + | |
- | // POSIX main signature
| + | |
- | //---------------------------------------------------------------------
| + | |
- | | + | |
- | int main(int argc, char **argv)
| + | |
- | {
| + | |
- | app_name = argv[0];
| + | |
- | | + | |
- | #endif
| + | |
- | | + | |
- | | + | |
- | // utils::tokeniser<char> t( app_name, "//" );
| + | |
- | // app_path = t.collate( 0, t.size()-3, "/" );
| + | |
- | | + | |
- | //---------------------------------------------------------------------
| + | |
- | // Common main body
| + | |
- | //---------------------------------------------------------------------
| + | |
- | | + | |
- | // The entire game is initialised, started and run in the FCom()
| + | |
- | // function.
| + | |
- | //
| + | |
- | try
| + | |
- | {
| + | |
- | Wartbed::getInstance( "QuickGUI Test" ).setFrameListener( new FrameListener );
| + | |
- | Wartbed::getInstance().setKeyListener( new KeyListener );
| + | |
- | Wartbed::getInstance().setMouseListener( new MouseListener );
| + | |
- | | + | |
- | // Must be done before OGRE's initialiseAllResourceGroups()
| + | |
- | //
| + | |
- | QuickGUI::registerScriptReader();
| + | |
- | | + | |
- | // QuickGUI needs at least one font to start, or it will throw
| + | |
- | // an exception. Also, we need to add a folder containing
| + | |
- | // QuickGUI .skinTypes (etc) files.
| + | |
- | //
| + | |
- | Ogre::ResourceGroupManager::getSingleton().addResourceLocation( "./Fonts", "FileSystem" );
| + | |
- | Ogre::ResourceGroupManager::getSingleton().addResourceLocation( "./QuickGUI", "FileSystem" );
| + | |
- | Ogre::ResourceGroupManager::getSingleton().addResourceLocation( "./QuickGUI/qgui.textures.zip", "Zip" );
| + | |
- | | + | |
- | // Instruct Ogre to go through all paths set by addResourceLocation
| + | |
- | // and add any comptible resources.
| + | |
- | //
| + | |
- | Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
| + | |
- | | + | |
- | // Apparently, QuickGUI must be dynamically created. The normal way
| + | |
- | // of interaction is even through a "getSingletonPtr()" method...
| + | |
- | //
| + | |
- | utils::shared_ptr<QuickGUI::Root> pQGUIRoot( new QuickGUI::Root() );
| + | |
- | | + | |
- | // These are the steps that must done to set up and prepare
| + | |
- | // QuickGUI for use:
| + | |
- | // * Load the types detected by Ogre's resource initialisation
| + | |
- | // * Creating a GUI manager object
| + | |
- | // * Creating a sheet
| + | |
- | // * Setting the active sheet
| + | |
- | //
| + | |
- | QuickGUI::SkinTypeManager::getSingleton().loadTypes();
| + | |
- | QuickGUI::GUIManagerDesc d;
| + | |
- | d.sceneManager = wb::ogre::pSceneManager;
| + | |
- | d.viewport = wb::ogre::pViewport;
| + | |
- | //d.queueID = Ogre::RENDER_QUEUE_OVERLAY;
| + | |
- | g_pGUIManager = pQGUIRoot->createGUIManager( d );
| + | |
- | g_pSheet = QuickGUI::SheetManager::getSingleton().createSheet( QuickGUI::Size(800,600) );
| + | |
- | g_pGUIManager->setActiveSheet( g_pSheet );
| + | |
- | | + | |
- | // Creating widgets:
| + | |
- | //
| + | |
- | // QuickGUI::Sheet* defaultSheet = mGUIManager->getActiveSheet();
| + | |
- | // QuickGUI::FactoryManager::getSingleton().getDescFactory();
| + | |
- | // QuickGUI::FactoryManager::getSingleton().getWidgetFactory();
| + | |
- | // QuickGUI::FactoryManager::getSingleton().getDescFactory()->getInstance("MyButtonDescObject");
| + | |
- | QuickGUI::ButtonDesc* bd =
| + | |
- | dynamic_cast<QuickGUI::ButtonDesc*>(
| + | |
- | QuickGUI::FactoryManager::getSingleton().
| + | |
- | getDescFactory()->
| + | |
- | getInstance<QuickGUI::ButtonDesc>("DefaultButtonDesc"));
| + | |
- | | + | |
- | bd->widget_name = "MyButton";
| + | |
- | bd->textDesc.segments.push_back( QuickGUI::TextSegment("micross.12",Ogre::ColourValue::Red,"Click Me!") );
| + | |
- | bd->widget_dimensions.size = QuickGUI::Size(100,25);
| + | |
- | bd->widget_dimensions.position = QuickGUI::Point(50,50);
| + | |
- | g_pButton = g_pSheet->createButton(bd);
| + | |
- | | + | |
- | | + | |
- | // Registering events with a widget. Since the event handlers
| + | |
- | // use a pointer-to-member-function signature we need to wrap
| + | |
- | // them in classes, which however could be useful...
| + | |
- | //
| + | |
- | GUIEventHandler handler;
| + | |
- | | + | |
- |
| + | |
- | Wartbed::getInstance().mainLoop();
| + | |
- | }
| + | |
- | | + | |
- | | + | |
- | //---------------------------------------------------------------------
| + | |
- | // Last-ditch exception handling
| + | |
- | //---------------------------------------------------------------------
| + | |
- | | + | |
- | catch (Ogre::Exception &e)
| + | |
- | {
| + | |
- | #if OGRE_PLATFORM == PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WIN32
| + | |
- | MessageBoxA( NULL, e.what(), "An exception has occurred!", MB_OK | MB_ICONERROR | MB_TASKMODAL );
| + | |
- | #else
| + | |
- | stderr << "An exception has occurred: " << e.what() << std::endl;
| + | |
- | #endif
| + | |
- | }
| + | |
- | | + | |
- | | + | |
- | catch (std::exception &e)
| + | |
- | {
| + | |
- | #if OGRE_PLATFORM == PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WIN32
| + | |
- | MessageBoxA( NULL, e.what(), "An exception has occurred!", MB_OK | MB_ICONERROR | MB_TASKMODAL );
| + | |
- | #else
| + | |
- | stderr << "An exception has occurred: " << e.what() << std::endl;
| + | |
- | #endif
| + | |
- | }
| + | |
- | | + | |
- | | + | |
- | catch (...)
| + | |
- | {
| + | |
- | #if OGRE_PLATFORM == PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WIN32
| + | |
- | MessageBoxA( NULL, "Unknows exception thrown!", "An exception has occurred!", MB_OK | MB_ICONERROR | MB_TASKMODAL );
| + | |
- | #else
| + | |
- | stderr << "An exception has occurred: " << e.what() << std::endl;
| + | |
- | #endif
| + | |
- | }
| + | |
- | | + | |
- | | + | |
- | return EXIT_SUCCESS;
| + | |
- | }
| + | |
- | | + | |
- | //-----------------------------------------------------------------------------
| + | |
- | //
| + | |
- | // ...end main function
| + | |
- | //=============================================================================
| + | |
- | </pre>
| + | |
| | | |
| ===MyGUI=== | | ===MyGUI=== |
Line 571: |
Line 48: |
| | | |
| ==Conclusions== | | ==Conclusions== |
- | CEGUI seems the most well-designed framework. In initial configuration and event bindings QuickGUI feels somewhat messier, and this can be suspected to permeate the entire framework. The function-identical CEGUI code is actually shorter than QuickGUI's (except that it only reacts to the left mouse button). CEGUI binds events to functions rather than methods, which is greatly to its advantage as if simplifies syntax without in practice losing flexibility. QuickGUI's widgets are all dragabble by default. If this is an advantage or not I haven't decided yet. | + | CEGUI and QuickGUI are as of yet seemingly the two best GUI options for OGRE. |
| + | |
| + | CEGUI seems the most well-designed framework, however not the easiest to work with due to monolithic and kitchen-sink design and obtuse messaging system. In initial configuration and event bindings QuickGUI feels somewhat messier, and this can be suspected to permeate the entire framework. Function-identical code is principally of identlical length between them (except that CEGUI's evaluation code only reacts to the left mouse button). CEGUI binds events to functions rather than methods, which is greatly to its advantage as if simplifies syntax without in practice losing flexibility. QuickGUI's widgets are all dragabble by default. If this is an advantage or not I haven't decided yet. |
| + | |
| + | I will do some practical tests to see which is easier to use in a realistic WARTBED context, and if the features of CEGUI are needed. |
| + | |
| + | [[category:WARTBED]] |
GUI systems are relatively complex beasts (which I know having designed a few!) and are good candidates for 3rd party libraries. Requirements are
Note that the screenshots below are not necessarily representative of the appearance of the frameworks since they all support skinning.
CEGUI and QuickGUI are as of yet seemingly the two best GUI options for OGRE.
CEGUI seems the most well-designed framework, however not the easiest to work with due to monolithic and kitchen-sink design and obtuse messaging system. In initial configuration and event bindings QuickGUI feels somewhat messier, and this can be suspected to permeate the entire framework. Function-identical code is principally of identlical length between them (except that CEGUI's evaluation code only reacts to the left mouse button). CEGUI binds events to functions rather than methods, which is greatly to its advantage as if simplifies syntax without in practice losing flexibility. QuickGUI's widgets are all dragabble by default. If this is an advantage or not I haven't decided yet.
I will do some practical tests to see which is easier to use in a realistic WARTBED context, and if the features of CEGUI are needed.