From 61275239ce9685d5269460c4cecbcd7e018dc97f Mon Sep 17 00:00:00 2001 From: "Martin Felis (berta)" Date: Sat, 11 Sep 2010 14:32:31 +0200 Subject: [PATCH] improvement of the text input and added some documentation --- asteroids/UserInterface.cc | 32 +++++++++++++++++++++++++++++--- engine/ControllerBase.cc | 12 ++++++++++++ engine/ControllerBase.h | 7 ++++--- engine/IMGUIControls.cc | 27 ++++++++++++++++++--------- engine/IMGUIControls.h | 15 +++++++++++++++ engine/doc/Mainpage.h | 3 ++- 6 files changed, 80 insertions(+), 16 deletions(-) diff --git a/asteroids/UserInterface.cc b/asteroids/UserInterface.cc index bf882a5..2f78fd1 100644 --- a/asteroids/UserInterface.cc +++ b/asteroids/UserInterface.cc @@ -536,11 +536,12 @@ void EnterPlayernameOverlay::Init () { } bool EnterPlayernameOverlay::OnKeyDown (const SDL_keysym &keysym) { - if (keysym.sym == SDLK_ESCAPE) { +/* if (keysym.sym == SDLK_ESCAPE) { GetModel()->SetGameState(GameStateMainMenu); GetController()->uistate.hotitem = 0; return true; } + */ return false; } @@ -569,18 +570,43 @@ void EnterPlayernameOverlay::Draw () { GetView()->SelectFont("console.ttf"); - Engine::GUI::Label (4, "A s t e r o i d s", right * 0.5 - 100, 180); + // If ESC, we want to go back to the main menu (warning: OpenGL cleanup has + // still to be performed! + if (Engine::GUI::CheckKeyPress(SDLK_ESCAPE)) { + GetModel()->SetGameState(GameStateMainMenu); + glPopMatrix (); - Engine::GUI::Label (1, "Enter your name: ", right * 0.5 - 100, 250); + glMatrixMode (GL_PROJECTION); + glPopMatrix (); + + glMatrixMode (GL_MODELVIEW); + return; + } + + Engine::GUI::Label (4, "A s t e r o i d s", right * 0.5 - 100, 180); // Make sure we have UNICODE processing enabled! GetController()->EnableTextinput(true); + // Enter your name std::string player_name = GetModel()->GetPlayerName(); + + Engine::GUI::Label (1, "Enter your name: ", right * 0.5 - 100, 250); + if (Engine::GUI::LineEdit (2, right * 0.5 + 20, 238, player_name, 16)) { GetModel()->SetPlayerName(player_name); } + // some test + static std::string otherstring("25blabla"); + + Engine::GUI::Label (6, "Enter your age : ", right * 0.5 - 100, 280); + + if (Engine::GUI::LineEdit (7, right * 0.5 + 20, 268, otherstring, 16)) { +// GetModel()->SetPlayerName(player_name); + } + + if (Engine::GUI::Button (3, "Start Game", right - 150 - 20, 500, 150, 40)) { GetModel()->SetGameState(GameStateRunning); } diff --git a/engine/ControllerBase.cc b/engine/ControllerBase.cc index 9741fc1..855d73a 100644 --- a/engine/ControllerBase.cc +++ b/engine/ControllerBase.cc @@ -270,6 +270,18 @@ int convert_keystring (const char *key_val) { return 0; } +const char* convert_keycode (const int &keycode) { + int i = 0; + while (key_table[i].keynum != keytable_last) { + if (key_table[i].keynum == keycode) + return key_table[i].keystr; + + i++; + } + + return NULL; +} + /* * Commands for the ControllerBase */ diff --git a/engine/ControllerBase.h b/engine/ControllerBase.h index fa60d59..97bef9d 100644 --- a/engine/ControllerBase.h +++ b/engine/ControllerBase.h @@ -13,7 +13,7 @@ class Module; * * See also http://sol.gfxile.net/imgui/ */ -struct UIState { +struct IMGUIState { int hotitem; int activeitem; @@ -34,6 +34,8 @@ struct UIState { /** \brief Converts a string into the corresponding keycode */ int convert_keystring (const char *key_val); +/** \brief Converts a key code value to the string that describes the value */ +const char* convert_keycode (const int &keycode); /** \brief All input is sent here and distributed from here * @@ -74,13 +76,12 @@ class ControllerBase : public Module { uistate.hotitem = 0; } void IMGUIClear () { - LogMessage ("Called IMGUIClear()"); uistate.hotitem = 0; uistate.kbditem = 0; } void IMGUIFinish (); - UIState uistate; + IMGUIState uistate; protected: /** \brief Initializes the system */ diff --git a/engine/IMGUIControls.cc b/engine/IMGUIControls.cc index 41c589c..093d6de 100644 --- a/engine/IMGUIControls.cc +++ b/engine/IMGUIControls.cc @@ -123,6 +123,9 @@ bool Button (int id, const char* caption, int x, int y, int w, int h) { // Keyboard Logic if (controller->uistate.kbditem == id) { + // Any unicode keys that were sent get cleared + controller->uistate.last_unicode = 0; + // We have to make sure, that we always clear the uistate.last_keysym // value, otherwise the same action might be repeated over and over. switch (controller->uistate.last_keysym) { @@ -165,32 +168,30 @@ bool LineEdit (int id, int x, int y, std::string &text_value, const int &maxleng int w = maxlength * 16; int h = 16; - // LogMessage ("id = %d hotitem = %d activeitem = %d kbditem = %d", id, controller->uistate.hotitem, controller->uistate.activeitem, controller->uistate.kbditem); +// LogMessage ("id = %d hotitem = %d activeitem = %d kbditem = %d key = %s", id, controller->uistate.hotitem, controller->uistate.activeitem, controller->uistate.kbditem, convert_keycode (controller->uistate.last_keysym)); // Check for hotness if (regionhit (x, y, w, h)) { controller->uistate.hotitem = id; if (controller->uistate.activeitem == 0 - && controller->GetButtonState(MouseButtonLeft)) + && controller->GetButtonState(MouseButtonLeft)) { controller->uistate.activeitem = id; - } - - // If nothing is selected - if (controller->uistate.hotitem != 0) { - controller->uistate.kbditem = controller->uistate.hotitem; + } } if (controller->uistate.kbditem == 0) { controller->uistate.hotitem = id; controller->uistate.kbditem = id; + controller->uistate.last_unicode = 0; + return false; } // Render glColor3f (0.2, 0.2, 0.2); DrawRect2D (x + 4, y + 4, w, h); - if (controller->uistate.hotitem == id - || controller->uistate.kbditem == id) { + // If we have keyboard focus, we highlight the widget + if ( controller->uistate.kbditem == id) { if (controller->uistate.activeitem == id) { glColor3f (0.8, 0.8, 0.8); DrawRect2D (x, y, w, h); @@ -284,10 +285,18 @@ bool LineEdit (int id, int x, int y, std::string &text_value, const int &maxleng && controller->uistate.hotitem == id && controller->uistate.activeitem == id) { controller->uistate.kbditem = id; + controller->uistate.last_unicode = 0; } return false; } +bool CheckKeyPress (int keycode) { + if (controller->uistate.last_keysym == keycode) + return true; + + return false; +} + }; }; diff --git a/engine/IMGUIControls.h b/engine/IMGUIControls.h index 78177a6..ffb821e 100644 --- a/engine/IMGUIControls.h +++ b/engine/IMGUIControls.h @@ -1,10 +1,17 @@ +/** \brief Header file for the IMGUI widgets + * + * \todo [med] Cyclying through widgets via tab and shift-tab + */ #ifndef _IMGUICONTROLS_H #define _IMGUICONTROLS_H +#include #include namespace Engine { +/** \brief IMGUI widgets and functions + */ namespace GUI { /** \brief Checks whether the mouse is in the given rectangle */ @@ -24,6 +31,14 @@ bool Button (int id, const char* caption, int x, int y, int w, int h); bool LineEdit (int id, int x, int y, std::string &text_value, const int &maxlength); +/** \brief Checks whether a given key was pressed + * + * This function can be used to check whether a single key (e.g. ESC) was + * pressed. This is useful when one wants to abort an action or quit from the + * main screen by pressing a single key. + */ +bool CheckKeyPress (int keycode); + }; }; diff --git a/engine/doc/Mainpage.h b/engine/doc/Mainpage.h index 4520861..c6b5551 100644 --- a/engine/doc/Mainpage.h +++ b/engine/doc/Mainpage.h @@ -72,7 +72,8 @@ * todos within the code have a look at the \ref todo. * * \todo [high] Create a simple racing or asteroids game - * \todo [med] Clear all references of EntityVisualState and EntityGameState + * \todo [high] Since introduction of the IMGUI pressing 'space' in the menu crashes the game +* \todo [med] Clear all references of EntityVisualState and EntityGameState * \todo [med] Clarify functionalities of CreateEntity, KillEntity, RegisterEntity, UnregisterEntity (which frees memory, which does only change the state of the Model?) * \todo [med] Add basic networking * \todo [med] Add serialization