viernes, 30 de abril de 2010

Personalizando nuestras aplicaciones 2ª (Botones, Labels ....)

En este tuturial aprenderemos a crear nuestro botones y labels, y demas utilidades que nos ofrece la GUI de Ogre.

En la clase SdkTraylistener, explicada un poco por encima en el tutoriales anteriores, esta clase ademas de crear botones, labels... un largo etc, es utilizada tambien para recojer sus estados. Vamos a intentar explicar una parte del codigo que se dedica a registrar los eventos de la ventana a la libreria de Ogre.

En el metodo BaseApplication::createFrameListener() esta el siguiente codigo:

//Este codigo es para meter registros de log en el fichero Ogre.log, de la capeta bin\debug o release
Ogre::LogManager::getSingletonPtr()->logMessage("*** Initializing OIS ***");
//Creamos una lista de parametros del OIS
OIS::ParamList pl;

Inicializamos un mejador de ventanas, tambien llamado en la API WIN32: HWND, digamos que es un identificador de la ventana, cada ventana de window que abres en tu S.O. necesita un identificador, pues estamos registrando el que nos a dado WindowsXP.

size_t windowHnd = 0;


//Creamos un flujo de entrada para crear valores String
std::ostringstream windowHndStr;


//El objeto mWindow es la venta fisica que acaba de crear nuestro programa en el S.O. le pasamos el windowHnd para que nos devuelva el identificador de ventna creado.
Se lo damos al flujo de entrada y se crea un String con un numero que se lo introducimos al ParamList
mWindow->getCustomAttribute("WINDOW", &windowHnd);
windowHndStr << windowHnd; pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str())); //Aqui creamos el InputManager con este PAramList creado anteriormente, que es el objeto padre que recojera cualquier evento producido en la ventana, raton, teclado, minimizar, maximizar.... mInputManager = OIS::InputManager::createInputSystem( pl ); //Creamos los objetos mKeyBoard y mMouse con ese InputManager y al ser el BaseApplication una clase derivada de KeyListener y MouseListener, les añadimos mKeyBoard y mMouse esta clase para recojer sus eventos. mKeyboard = static_cast(mInputManager->createInputObject( OIS::OISKeyboard, true ));
mMouse = static_cast(mInputManager->createInputObject( OIS::OISMouse, true ));


mMouse->setEventCallback(this);
mKeyboard->setEventCallback(this);


//Aqui establecemos el tamaño de ventan para darle un ancho y alto al nuestro raton
windowResized(mWindow);


//Registramos en Ogre la ventana y el BAseApplication que deriva de WIndowEventListener
Ogre::WindowEventUtilities::addWindowEventListener(mWindow, this);


//Aqui inicializamos en objeto SdkTrayListener con la ventana, el raton y el BaseApplication
mTrayMgr = new OgreBites::SdkTrayManager("InterfaceName", mWindow, mMouse, this);
//Aqui muestra el panel de FPS
mTrayMgr->showFrameStats(OgreBites::TL_BOTTOMLEFT);
//Inicializa nuestro Logo, ya modificado en el tutorial anterior
mTrayMgr->showLogo(OgreBites::TL_BOTTOMRIGHT);


//Una vez explicado esto ya entendemos como se enlaza la ventana con la librearia Ogre y OIS, para recojer los eventos del MouseListener y KeyListener y sus metodos:


virtual bool keyPressed( const OIS::KeyEvent &arg );
virtual bool keyReleased( const OIS::KeyEvent &arg );
virtual bool mouseMoved( const OIS::MouseEvent &arg );
virtual bool mousePressed( const OIS::MouseEvent &arg, OIS::MouseButtonID id );
virtual bool mouseReleased( const OIS::MouseEvent &arg, OIS::MouseButtonID id );

Una vez echo esto en el metodo createFrameListener() al final vamos a crear un boton y un label :

mTrayMgr->createButton(OgreBites::TL_BOTTOM, "Boton","Esto es un boton",200);
mTrayMgr->createLabel(OgreBites::TL_TOP,"Label","FrakTeam Logo",400);

Con estos metodos creamos dos Widgets dentro de la clase mTrayMgr, los Widgets con la clase Padre de todos los elementos creado de SdkTray. Utilizamos el metodo mousePressed, para saber que ha pulsado:

bool personalizando2::mousePressed(const OIS::MouseEvent &evt, OIS::MouseButtonID id){
if(mTrayMgr->injectMouseDown(evt,id)){
OgreBites::Label *label = static_cast(mTrayMgr->getWidget("Label"));
OgreBites::Button *boton = static_cast(mTrayMgr->getWidget("Boton"));
if(boton->getState() == OgreBites::BS_DOWN){
label->setCaption("Has pulsado el boton");
} else {


label->setCaption("No es el boton");
}
return true;
} else {
static_cast(mTrayMgr->getWidget("Label"))->setCaption("Has pulsado en vacio");
}
mCameraMan->injectMouseDown(evt,id);
return true;


}

Compilamos y veremos algo así:


Como vemos en este codigo cojemos el evento MouseEvent y el boton pulsado del raton MouseButtonID, y se los pasamos a mTrayMgr->injectMouseDown(), este metodo busca todos sus Widgets, creado por la posición y cambia el estado del pulsado por el cursor, dependiendo la posición del mismo.

Un vez pasado el metodo injectMouseDown, si hemos pulsado el boton habrá cambiado su estado, utilizamos el metodo getWidget(Nombre), y le realizamos un static_cast a OgreBites::Button, hacemos la conversión de Widgets a Button, preguntamos por su estado y vemos que es OgreBitess::BS_DOWN, y cambiamos el valor del caption del Label, realizando la misma operación de sttatic_cast.

Esto es un ejemplo, pero lo suyo es tener objetos Button y Label como privados, para no tener que realizar un static_cast cada vez que pulsemos un boton en nuestra aplicación, de todas formas solo es un ejemplo.

El metodo de mCameraMan->injectMouseDown(), como expliqué en tutoriales anteriores, este objeto es para utilizar los eventos de la camara, si no hemos pulsado ningun Widgets, entoces le pasa el valor del raton a la camara.

Aqui os paso el Codigo de ejemplo por si lo quereis ver y realizar Debug. SRC Ejemplo

Aqui os paso los binarios del programa solo para Windows. Se ejecutará en modod OpenGL, si quieres ejecutarlo en modo DirectX, necesitas terner instalado los Directx en tu equipo y descomentar el fichero plugins.cfg, la linea:

Plugin=RenderSystem_Direct3D9
# Plugin=RenderSystem_Direct3D10
# Plugin=RenderSystem_Direct3D11

Descomenta dependiendo la que tengas.

Binarios Ejemplo

No hay comentarios:

Publicar un comentario

Gracias por tu comentario! :)