File DialogBuild.cpp
CEGUI build dialog - implementation
Welcome to the new Ogre Wiki!
If you haven't done so already, be sure to visit the Wiki Portal to read about how the wiki works. Especially the Ogre Wiki Overview page.
If you haven't done so already, be sure to visit the Wiki Portal to read about how the wiki works. Especially the Ogre Wiki Overview page.
DialogBuild.cpp
#include "stdafx.h" #include "DialogBuild.h" #include "InputHandler.h" #include "PlayState.h" #include "Common/StaticEntity.h" #include "Common/EntityMgr.h" // these must match the IDs assigned in the layout const unsigned int DialogBuild::buttonCancelID = 1; const unsigned int DialogBuild::buttonStructuresID = 21; const unsigned int DialogBuild::buttonBioUnitsID = 22; const unsigned int DialogBuild::buttonMechsID = 23; const unsigned int DialogBuild::buttonVehiclesID = 24; const unsigned int DialogBuild::scrollBarID = 2; const unsigned int DialogBuild::buttonID[DIALOG_BUTTON_COUNT] = { 3, 5, 7, 9, 11, 13 }; const unsigned int DialogBuild::buttonLabelID[DIALOG_BUTTON_COUNT] = { 4, 6, 8, 10, 12, 14 }; const unsigned int DialogBuild::buttonTextID[DIALOG_BUTTON_COUNT] = { 15, 16, 17, 18, 19, 20 }; // Size of each Render-To-Texture texture, in pixels #define RTT_WINDOW_SIZE 128 // World height at which to place each Entity #define OBJECT_WORLD_POS_Y (-500.0) // Type of Entity to be displayed when first opening the dialog box #define INITIAL_ITEM_TYPE ItemType_Building DialogBuild::DialogBuild() : rootWindow(CEGUI::WindowManager::getSingleton().loadWindowLayout("DialogBuild.layout", "Build")) { using namespace CEGUI; Window* parent; itemTypeToDisplay = INITIAL_ITEM_TYPE; scrollOffset = 0; scrollbar = (Scrollbar *)rootWindow->getChild(scrollBarID); // we will destroy the DialogBuild box windows ourselves rootWindow->setDestroyedByParent(false); // Do events wire-up scrollbar->subscribeEvent(Scrollbar::EventScrollPositionChanged, Event::Subscriber(&DialogBuild::handleScrollChanged, this)); rootWindow->subscribeEvent(Window::EventKeyDown, Event::Subscriber(&DialogBuild::HandleKeyDownEvents, this)); rootWindow->getChild(buttonCancelID)->subscribeEvent(PushButton::EventClicked, Event::Subscriber(&DialogBuild::handleButtonCancel, this)); rootWindow->getChild(buttonStructuresID)->subscribeEvent(PushButton::EventClicked, Event::Subscriber(&DialogBuild::handleButtonStructures, this)); rootWindow->getChild(buttonBioUnitsID)->subscribeEvent(PushButton::EventClicked, Event::Subscriber(&DialogBuild::handleButtonBioUnits, this)); rootWindow->getChild(buttonMechsID)->subscribeEvent(PushButton::EventClicked, Event::Subscriber(&DialogBuild::handleButtonMechs, this)); rootWindow->getChild(buttonVehiclesID)->subscribeEvent(PushButton::EventClicked, Event::Subscriber(&DialogBuild::handleButtonVehicles, this)); rootWindow->getChild(buttonID[0])->subscribeEvent(PushButton::EventClicked, Event::Subscriber(&DialogBuild::handleButton00, this)); rootWindow->getChild(buttonID[1])->subscribeEvent(PushButton::EventClicked, Event::Subscriber(&DialogBuild::handleButton01, this)); rootWindow->getChild(buttonID[2])->subscribeEvent(PushButton::EventClicked, Event::Subscriber(&DialogBuild::handleButton02, this)); rootWindow->getChild(buttonID[3])->subscribeEvent(PushButton::EventClicked, Event::Subscriber(&DialogBuild::handleButton03, this)); rootWindow->getChild(buttonID[4])->subscribeEvent(PushButton::EventClicked, Event::Subscriber(&DialogBuild::handleButton04, this)); rootWindow->getChild(buttonID[5])->subscribeEvent(PushButton::EventClicked, Event::Subscriber(&DialogBuild::handleButton05, this)); int buttonIndex; Ogre::String cameraName; Ogre::String texName; Ogre::String matName; Ogre::String lightName; CEGUI::String imageSetName; for (buttonIndex = 0; buttonIndex < DIALOG_BUTTON_COUNT; buttonIndex++) { displayedEntity[buttonIndex] = NULL; // Create Render-To-Texture texture texName = "RttTex_" + StringConverter::toString(buttonIndex); rttTex[buttonIndex] = global->root->getRenderSystem()->createRenderTexture(texName, RTT_WINDOW_SIZE, RTT_WINDOW_SIZE, TEX_TYPE_2D, PF_R8G8B8); rttTex[buttonIndex]->setActive(false); cameraName = "ButtonCam_" + StringConverter::toString(buttonIndex); rttCam[buttonIndex] = global->sceneMgr->createCamera(cameraName); rttCam[buttonIndex]->setAspectRatio((Real)global->renderWindow->getViewport(0)->getActualWidth() / (Real)global->renderWindow->getViewport(0)->getActualHeight()); rttNode[buttonIndex] = global->sceneMgr->getRootSceneNode()->createChildSceneNode(cameraName); rttNode[buttonIndex]->setFixedYawAxis(TRUE); matName = "RttMat_" + StringConverter::toString(buttonIndex); MaterialPtr material = MaterialManager::getSingleton().create(matName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); material->getTechnique(0)->getPass(0)->setDepthCheckEnabled(false); material->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false); rttTex[buttonIndex]->addListener(this); Viewport *v = rttTex[buttonIndex]->addViewport(rttCam[buttonIndex]); v->setClearEveryFrame(true); v->setBackgroundColour(ColourValue(0.1, 0.2, 0.7)); v->setOverlaysEnabled(false); // Set the CEGUI Button's image to our new RTT Ogre::TexturePtr ogreTex = Ogre::TextureManager::getSingletonPtr()->getByName(texName); OgreCEGUITexture* ceguiTex = (OgreCEGUITexture*)global->guiRenderer->createTexture(); ceguiTex->setOgreTexture(ogreTex); imageSetName = "ButtonTextureImageset_" + StringConverter::toString(buttonIndex); Imageset* textureImageSet = ImagesetManager::getSingleton().createImageset(imageSetName, ceguiTex); textureImageSet->defineImage("RttTex", Point(0.0f, 0.0f), Size(ceguiTex->getWidth(), ceguiTex->getHeight()), Point(0.0f,0.0f)); imageSetName = "set:ButtonTextureImageset_" + StringConverter::toString(buttonIndex) + " image:RttTex"; rootWindow->getChild(buttonID[buttonIndex])->setProperty("NormalImage", imageSetName); rootWindow->getChild(buttonID[buttonIndex])->setProperty("HoverImage", imageSetName); rootWindow->getChild(buttonID[buttonIndex])->setProperty("PushedImage", imageSetName); // Create a spotlight for each Entity lightName = "RttLight_" + StringConverter::toString(buttonIndex); spotLight[buttonIndex] = global->sceneMgr->createLight(lightName); spotLight[buttonIndex]->setType(Light::LT_SPOTLIGHT); spotLight[buttonIndex]->setDiffuseColour(0.93, 0.93, 0.93); spotLight[buttonIndex]->setSpecularColour(0.3, 0.3, 0.3); spotLight[buttonIndex]->setAttenuation(5000.0, 1.0, 0.01, 0.0); spotLight[buttonIndex]->setSpotlightRange(Degree(30), Degree(50), 1.0); spotLight[buttonIndex]->setVisible(false); } hideObjectsNode = global->sceneMgr->getRootSceneNode()->createChildSceneNode("HiddenButtonEntityNode"); hideObjectsNode->setVisible(false); // attach this window if parent is valid parent = System::getSingleton().getGUISheet(); if (parent) parent->addChildWindow(rootWindow); rootWindow->hide(); isShown = FALSE; } DialogBuild::~DialogBuild() { // destroy the windows that we loaded earlier CEGUI::WindowManager::getSingleton().destroyWindow(rootWindow); } bool DialogBuild::HandleKeyDownEvents(const CEGUI::EventArgs& args) { if (isShown) { SDLKey lastKeyHit = InputHandler::getInstance()->GetLastKeyHit(); if (lastKeyHit == SDLK_ESCAPE) hide(); return TRUE; } else { return FALSE; } } void DialogBuild::FrameStarted(Real timeElapsed) { if (!isShown) return; int buttonIndex; // Spin each of the objects around their axis for (buttonIndex = 0; buttonIndex < DIALOG_BUTTON_COUNT; buttonIndex++) rttNode[buttonIndex]->yaw((Radian)(timeElapsed * 0.8)); } void DialogBuild::preRenderTargetUpdate(const RenderTargetEvent& evt) { if (isShown) { #if USE_SEPERATE_ROOT_NODE global->rootNode->setVisible(false); #endif global->sceneMgr->addSpecialCaseRenderQueue(RENDER_QUEUE_MAIN); global->sceneMgr->setSpecialCaseRenderQueueMode(SceneManager::SCRQM_INCLUDE); } } void DialogBuild::postRenderTargetUpdate(const RenderTargetEvent& evt) { if (isShown) { #if USE_SEPERATE_ROOT_NODE global->rootNode->setVisible(true); #endif global->sceneMgr->clearSpecialCaseRenderQueues(); global->sceneMgr->setSpecialCaseRenderQueueMode(SceneManager::SCRQM_EXCLUDE); } } bool DialogBuild::handleScrollChanged(const CEGUI::EventArgs& args) { int newScrollOffset; // This event gets thrown when the scroll bar position moves even a little bit, // and may not cause a change in the scrollOffset. // Only do an update if scrollOffset actually changes. newScrollOffset = (int)scrollbar->getScrollPosition() * DIALOG_BUTTON_COLUMNS; if (newScrollOffset != scrollOffset) { scrollOffset = newScrollOffset; PopulateButtons(); } return true; } bool DialogBuild::handleButtonCancel(const CEGUI::EventArgs& args) { hide(); return true; } bool DialogBuild::handleButtonStructures(const CEGUI::EventArgs& args) { if (itemTypeToDisplay == ItemType_Building) return true; itemTypeToDisplay = ItemType_Building; InitializeForItemType(); PopulateButtons(); return true; } bool DialogBuild::handleButtonBioUnits(const CEGUI::EventArgs& args) { if (itemTypeToDisplay == ItemType_Character) return true; itemTypeToDisplay = ItemType_Character; InitializeForItemType(); PopulateButtons(); return true; } bool DialogBuild::handleButtonMechs(const CEGUI::EventArgs& args) { if (itemTypeToDisplay == ItemType_Mech) return true; itemTypeToDisplay = ItemType_Mech; InitializeForItemType(); PopulateButtons(); return true; } bool DialogBuild::handleButtonVehicles(const CEGUI::EventArgs& args) { if (itemTypeToDisplay == ItemType_Vehicle) return true; itemTypeToDisplay = ItemType_Vehicle; InitializeForItemType(); PopulateButtons(); return true; } // User hit the Entity button at Row 0, Column 0 bool DialogBuild::handleButton00(const CEGUI::EventArgs& args) { hide(); global->playState->SetPlaceEntityType(displayedEntityType[0]); return true; } bool DialogBuild::handleButton01(const CEGUI::EventArgs& args) { hide(); global->playState->SetPlaceEntityType(displayedEntityType[1]); return true; } bool DialogBuild::handleButton02(const CEGUI::EventArgs& args) { hide(); global->playState->SetPlaceEntityType(displayedEntityType[2]); return true; } bool DialogBuild::handleButton03(const CEGUI::EventArgs& args) { hide(); global->playState->SetPlaceEntityType(displayedEntityType[3]); return true; } bool DialogBuild::handleButton04(const CEGUI::EventArgs& args) { hide(); global->playState->SetPlaceEntityType(displayedEntityType[4]); return true; } bool DialogBuild::handleButton05(const CEGUI::EventArgs& args) { hide(); global->playState->SetPlaceEntityType(displayedEntityType[5]); return true; } // The itemType to be displayed changed, either by the dialog being initialized for the first time, // or the user pressed a button to change to a different itemType. void DialogBuild::InitializeForItemType(void) { int entityIndex; int entityCount; EntityTemplate * entityTemplate; scrollOffset = 0; // Count the total number of Entities eligible to be displayed in the Build dialog. entityCount = 0; for (entityIndex = 0; entityIndex < global->entityMgr->GetEntityTemplateCount(); entityIndex++) { entityTemplate = global->entityMgr->GetEntityTemplateFromIndex(entityIndex); if (entityTemplate && (entityTemplate->itemType == itemTypeToDisplay)) entityCount += 1; } if (entityCount <= DIALOG_BUTTON_COUNT) { // There are fewer or equal number of Entities to be displayed than there are buttons, so we don't need a scrollbar rootWindow->getChild(scrollBarID)->hide(); return; } scrollbar->show(); scrollbar->setScrollPosition(0.0); scrollbar->setProperty("DocumentSize", StringConverter::toString((int)(entityCount / DIALOG_BUTTON_COLUMNS) + 1)); scrollbar->setProperty("PageSize", StringConverter::toString(DIALOG_BUTTON_ROWS)); scrollbar->setProperty("StepSize", CEGUI::String("1")); scrollbar->setProperty("OverlapSize", CEGUI::String("1")); } void DialogBuild::PopulateButtons(void) { int buttonIndex; int entityIndex; int scrollCount; Real cameraDist; char meshName[50]; Ogre::String modelName; Ogre::Vector3 cameraPosition; Ogre::Vector3 cameraTarget; Ogre::Vector3 lightDirection; EntityTemplate * entityTemplate; // Move entityIndex up to the value of scrollOffset, and continue from there entityIndex = 0; scrollCount = 0; while ((scrollCount < (scrollOffset)) && (entityIndex < global->entityMgr->GetEntityTemplateCount())) { entityTemplate = global->entityMgr->GetEntityTemplateFromIndex(entityIndex); if (entityTemplate && (entityTemplate->itemType == itemTypeToDisplay)) scrollCount += 1; entityIndex += 1; } // De-initialize all our buttons to make them ready to display a new Entity or be hidden if not needed. // They are all hidden here, and unhidden later if needed. for (buttonIndex = 0; buttonIndex < DIALOG_BUTTON_COUNT; buttonIndex++) { if (displayedEntity[buttonIndex] != NULL) { // Move any existing Entities that we already created for our buttons to the hidden sceneNode. rttNode[buttonIndex]->detachObject(displayedEntity[buttonIndex]); hideObjectsNode->attachObject(displayedEntity[buttonIndex]); displayedEntity[buttonIndex] = NULL; } rttTex[buttonIndex]->setActive(false); spotLight[buttonIndex]->setVisible(false); rootWindow->getChild(buttonID[buttonIndex])->hide(); rootWindow->getChild(buttonLabelID[buttonIndex])->hide(); rootWindow->getChild(buttonTextID[buttonIndex])->hide(); displayedEntityType[buttonIndex] = 0; } for (buttonIndex = 0; buttonIndex < DIALOG_BUTTON_COUNT; buttonIndex++) { if (entityIndex < global->entityMgr->GetEntityTemplateCount()) { // Find the next EntityTemplate that should be displayed on a button. while (entityIndex < global->entityMgr->GetEntityTemplateCount()) { entityTemplate = global->entityMgr->GetEntityTemplateFromIndex(entityIndex); if (entityTemplate && (entityTemplate->itemType == itemTypeToDisplay)) break; entityIndex += 1; } if (entityTemplate && (entityIndex < global->entityMgr->GetEntityTemplateCount())) { strcpy(meshName, entityTemplate->fileName1); strcat(meshName, ".mesh"); rttTex[buttonIndex]->setActive(true); rootWindow->getChild(buttonID[buttonIndex])->show(); rootWindow->getChild(buttonLabelID[buttonIndex])->show(); rootWindow->getChild(buttonTextID[buttonIndex])->show(); displayedEntityType[buttonIndex] = entityIndex; modelName = entityTemplate->name; modelName += "_DialogBuild_" + StringConverter::toString(entityIndex); // Try to grab a saved copy of the Entity we want from the hidden sceneNode. try { displayedEntity[buttonIndex] = (Ogre::Entity *)hideObjectsNode->getAttachedObject(modelName); hideObjectsNode->detachObject(displayedEntity[buttonIndex]); } catch(...) { // Did not already create this type Entity. Create a new one. displayedEntity[buttonIndex] = global->sceneMgr->createEntity(modelName, meshName); assert(_T("DialogBuild::show myModel == NULL") && (displayedEntity != NULL)); } rttNode[buttonIndex]->attachObject(displayedEntity[buttonIndex]); rttNode[buttonIndex]->setPosition(Ogre::Vector3(100.0 * entityIndex, OBJECT_WORLD_POS_Y, 0)); if (entityTemplate->collisionHeight > entityTemplate->collisionRadius) cameraDist = entityTemplate->collisionHeight * 1.5; else cameraDist = entityTemplate->collisionRadius * 2.5; cameraPosition = Ogre::Vector3(100.0 * entityIndex, OBJECT_WORLD_POS_Y + entityTemplate->collisionHeight * 1.2, cameraDist); cameraTarget = Ogre::Vector3(100.0 * entityIndex, OBJECT_WORLD_POS_Y + entityTemplate->collisionHeight * 0.4, 0.0); lightDirection = cameraTarget - cameraPosition; lightDirection.normalise(); rttCam[buttonIndex]->setPosition(cameraPosition); rttCam[buttonIndex]->lookAt(cameraTarget); spotLight[buttonIndex]->setPosition(cameraPosition); spotLight[buttonIndex]->setVisible(true); spotLight[buttonIndex]->setDirection(lightDirection); rootWindow->getChild(buttonLabelID[buttonIndex])->setText(entityTemplate->name); // TODO: populate this text box with real statistics regarding this Entity. rootWindow->getChild(buttonTextID[buttonIndex])->setText("Cost: " + StringConverter::toString(randInt(500,1000))); } else { // Finished going through all our EntityTemplates and could find no more to display. return; } } entityIndex += 1; } } void DialogBuild::show(void) { if (isShown) return; isShown = TRUE; // Force the Dialog to display the first "page" every time it opens. itemTypeToDisplay = INITIAL_ITEM_TYPE; InitializeForItemType(); PopulateButtons(); rootWindow->show(); rootWindow->moveToFront(); InputHandler::getInstance()->SetGUIHasFocus(TRUE); } void DialogBuild::hide(void) { rootWindow->hide(); InputHandler::getInstance()->SetGUIHasFocus(FALSE); if (!isShown) return; isShown = FALSE; int buttonIndex; for (buttonIndex = 0; buttonIndex < DIALOG_BUTTON_COUNT; buttonIndex++) { rttTex[buttonIndex]->setActive(false); if (displayedEntity[buttonIndex] != NULL) { // Move any existing Entities that we already created for our buttons to the hidden sceneNode. rttNode[buttonIndex]->detachObject(displayedEntity[buttonIndex]); hideObjectsNode->attachObject(displayedEntity[buttonIndex]); displayedEntity[buttonIndex] = NULL; } } } void DialogBuild::toggleVisibility() { if (isShown) hide(); else show(); } bool DialogBuild::isVisible() const { return isShown; }
Contributors to this page: jacmoe
and
OgreWikiBot
.
Page last modified on Saturday 02 of January, 2010 21:22:10 UTC by jacmoe
.
The content on this page is licensed under the terms of the Creative Commons Attribution-ShareAlike License.
As an exception, any source code contributed within the content is released into the Public Domain.

