diff --git a/Makefile b/Makefile index 25e58a9..39ab170 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ # It's usually sufficient to change just the target name and source file list # and be sure that CXX is set to a valid compiler TARGET = test -SOURCE_FILES = guiInventoryMenu.cpp irrlichtwrapper.cpp guiPauseMenu.cpp defaultsettings.cpp mapnode.cpp tile.cpp voxel.cpp mapblockobject.cpp inventory.cpp debug.cpp serialization.cpp light.cpp filesys.cpp connection.cpp environment.cpp client.cpp server.cpp socket.cpp mapblock.cpp mapsector.cpp heightmap.cpp map.cpp player.cpp utility.cpp main.cpp test.cpp +SOURCE_FILES = guiTextInputMenu.cpp guiInventoryMenu.cpp irrlichtwrapper.cpp guiPauseMenu.cpp defaultsettings.cpp mapnode.cpp tile.cpp voxel.cpp mapblockobject.cpp inventory.cpp debug.cpp serialization.cpp light.cpp filesys.cpp connection.cpp environment.cpp client.cpp server.cpp socket.cpp mapblock.cpp mapsector.cpp heightmap.cpp map.cpp player.cpp utility.cpp main.cpp test.cpp SOURCES = $(addprefix src/, $(SOURCE_FILES)) BUILD_DIR = build OBJECTS = $(addprefix $(BUILD_DIR)/, $(SOURCE_FILES:.cpp=.o)) diff --git a/src/guiPauseMenu.cpp b/src/guiPauseMenu.cpp index ed4f0cd..2a0b3cb 100644 --- a/src/guiPauseMenu.cpp +++ b/src/guiPauseMenu.cpp @@ -17,7 +17,6 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ - #include "guiPauseMenu.h" #include "debug.h" #include "serialization.h" @@ -174,7 +173,7 @@ bool GUIPauseMenu::OnEvent(const SEvent& event) } } } - + return Parent ? Parent->OnEvent(event) : false; } diff --git a/src/guiPauseMenu.h b/src/guiPauseMenu.h index 7c37af8..187d20e 100644 --- a/src/guiPauseMenu.h +++ b/src/guiPauseMenu.h @@ -17,7 +17,6 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ - #ifndef GUIPAUSEMENU_HEADER #define GUIPAUSEMENU_HEADER diff --git a/src/guiTextInputMenu.cpp b/src/guiTextInputMenu.cpp new file mode 100644 index 0000000..8a9da34 --- /dev/null +++ b/src/guiTextInputMenu.cpp @@ -0,0 +1,168 @@ +/* +Minetest-c55 +Copyright (C) 2010 celeron55, Perttu Ahola + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "guiTextInputMenu.h" +#include "debug.h" +#include "serialization.h" +#include + +GUITextInputMenu::GUITextInputMenu(gui::IGUIEnvironment* env, + gui::IGUIElement* parent, s32 id, + int *active_menu_count, + TextDest *dest, + std::wstring initial_text +): + GUIModalMenu(env, parent, id, active_menu_count), + m_dest(dest), + m_initial_text(initial_text) +{ +} + +GUITextInputMenu::~GUITextInputMenu() +{ + removeChildren(); +} + +void GUITextInputMenu::removeChildren() +{ + { + gui::IGUIElement *e = getElementFromId(256); + if(e != NULL) + e->remove(); + } + { + gui::IGUIElement *e = getElementFromId(257); + if(e != NULL) + e->remove(); + } +} + +void GUITextInputMenu::regenerateGui(v2u32 screensize) +{ + std::wstring text; + + { + gui::IGUIElement *e = getElementFromId(256); + if(e != NULL) + { + text = e->getText(); + } + else + { + text = m_initial_text; + m_initial_text = L""; + } + } + + /* + Remove stuff + */ + removeChildren(); + + /* + Calculate new sizes and positions + */ + core::rect rect( + screensize.X/2 - 580/2, + screensize.Y/2 - 300/2, + screensize.X/2 + 580/2, + screensize.Y/2 + 300/2 + ); + + DesiredRect = rect; + recalculateAbsolutePosition(false); + + v2s32 size = rect.getSize(); + + /* + Add stuff + */ + { + core::rect rect(0, 0, 300, 30); + rect = rect + v2s32(size.X/2-300/2, size.Y/2-30/2-25); + gui::IGUIElement *e = + Environment->addEditBox(text.c_str(), rect, true, this, 256); + Environment->setFocus(e); + } + { + core::rect rect(0, 0, 140, 30); + rect = rect + v2s32(size.X/2-140/2, size.Y/2-30/2+25); + Environment->addButton(rect, this, 257, L"Proceed"); + } +} + +void GUITextInputMenu::drawMenu() +{ + gui::IGUISkin* skin = Environment->getSkin(); + if (!skin) + return; + video::IVideoDriver* driver = Environment->getVideoDriver(); + + video::SColor bgcolor(140,0,0,0); + driver->draw2DRectangle(bgcolor, AbsoluteRect, &AbsoluteClippingRect); + + gui::IGUIElement::draw(); +} + +bool GUITextInputMenu::OnEvent(const SEvent& event) +{ + if(event.EventType==EET_KEY_INPUT_EVENT) + { + if(event.KeyInput.Key==KEY_ESCAPE && event.KeyInput.PressedDown) + { + quitMenu(); + return true; + } + } + if(event.EventType==EET_GUI_EVENT) + { + if(event.GUIEvent.EventType==gui::EGET_ELEMENT_FOCUS_LOST + && isVisible()) + { + if(!canTakeFocus(event.GUIEvent.Element)) + { + dstream<<"GUITextInputMenu: Not allowing focus change." + <getID()) + { + case 257: + if(m_dest) + { + gui::IGUIElement *e = getElementFromId(256); + if(e != NULL) + { + m_dest->gotText(e->getText()); + } + delete m_dest; + } + quitMenu(); + break; + } + } + } + + return Parent ? Parent->OnEvent(event) : false; +} + diff --git a/src/guiTextInputMenu.h b/src/guiTextInputMenu.h new file mode 100644 index 0000000..2efc190 --- /dev/null +++ b/src/guiTextInputMenu.h @@ -0,0 +1,59 @@ +/* +Minetest-c55 +Copyright (C) 2010 celeron55, Perttu Ahola + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef GUITEXTINPUTMENU_HEADER +#define GUITEXTINPUTMENU_HEADER + +#include "common_irrlicht.h" +#include "modalMenu.h" +#include "utility.h" +#include + +struct TextDest +{ + virtual void gotText(std::wstring text) = 0; +}; + +class GUITextInputMenu : public GUIModalMenu +{ +public: + GUITextInputMenu(gui::IGUIEnvironment* env, + gui::IGUIElement* parent, s32 id, + int *active_menu_count, + TextDest *dest, + std::wstring initial_text); + ~GUITextInputMenu(); + + void removeChildren(); + /* + Remove and re-add (or reposition) stuff + */ + void regenerateGui(v2u32 screensize); + + void drawMenu(); + + bool OnEvent(const SEvent& event); + +private: + TextDest *m_dest; + std::wstring m_initial_text; +}; + +#endif + diff --git a/src/main.cpp b/src/main.cpp index 4d8a952..fe0bfb0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -224,11 +224,12 @@ TODO: Convert the text input system to use a modal menu... or something #include "constants.h" #include "strfnd.h" #include "porting.h" -#include "guiPauseMenu.h" #include "irrlichtwrapper.h" #include "gettime.h" #include "porting.h" +#include "guiPauseMenu.h" #include "guiInventoryMenu.h" +#include "guiTextInputMenu.h" IrrlichtWrapper *g_irrlicht; @@ -287,12 +288,6 @@ Queue inventory_action_queue; // This is a copy of the inventory that the client's environment has Inventory local_inventory; -std::wstring g_text_buffer; -bool g_text_buffer_accepted = false; - -// When true, the mouse and keyboard are grabbed -bool g_game_focused = true; - /* Debug streams */ @@ -334,6 +329,15 @@ public: // This is the one method that we have to implement virtual bool OnEvent(const SEvent& event) { + /* + React to nothing here if a menu is active + */ + if(noMenuActive() == false) + { + clearInput(); + return false; + } + // Remember whether each key is down or up if(event.EventType == irr::EET_KEY_INPUT_EVENT) { @@ -342,82 +346,46 @@ public: if(event.KeyInput.PressedDown) { //dstream<<"Pressed key: "<<(char)event.KeyInput.Key< 0) - g_text_buffer = g_text_buffer.substr - (0, g_text_buffer.size()-1); - } - else - { - wchar_t wc = event.KeyInput.Char; - if(wc != 0) - g_text_buffer += wc; - } - } - //if(pauseMenu != NULL) + /* + Launch menus + */ + if(guienv != NULL && guiroot != NULL && g_device != NULL) { if(event.KeyInput.Key == irr::KEY_ESCAPE) { - if(g_game_focused == true && noMenuActive()) - { - dstream<drop(); - return true; - } + dstream<drop(); + return true; } - } - - //if(inventoryMenu != NULL) - if(guienv != NULL && guiroot != NULL && g_device != NULL) - { if(event.KeyInput.Key == irr::KEY_KEY_I) { - if(g_game_focused == true && noMenuActive()) - { - dstream<drop(); - return true; - } + dstream<drop(); + return true; } } // Material selection if(event.KeyInput.Key == irr::KEY_KEY_F) { - if(g_game_focused == true) - { - if(g_selected_item < PLAYER_INVENTORY_SIZE-1) - g_selected_item++; - else - g_selected_item = 0; - dstream<clear(); - g_game_focused = true; -} - -void unFocusGame() -{ - g_game_focused = false; -} - class RealInputHandler : public InputHandler { public: @@ -617,14 +579,10 @@ public: virtual bool getLeftClicked() { - if(g_game_focused == false) - return false; return m_receiver->leftclicked; } virtual bool getRightClicked() { - if(g_game_focused == false) - return false; return m_receiver->rightclicked; } virtual void resetLeftClicked() @@ -638,14 +596,10 @@ public: virtual bool getLeftReleased() { - if(g_game_focused == false) - return false; return m_receiver->leftreleased; } virtual bool getRightReleased() { - if(g_game_focused == false) - return false; return m_receiver->rightreleased; } virtual void resetLeftReleased() @@ -1015,11 +969,6 @@ private: Text input system */ -struct TextDest -{ - virtual void sendText(std::string text) = 0; -}; - struct TextDestSign : public TextDest { TextDestSign(v3s16 blockpos, s16 id, Client *client) @@ -1028,11 +977,12 @@ struct TextDestSign : public TextDest m_id = id; m_client = client; } - void sendText(std::string text) + void gotText(std::wstring text) { + std::string ntext = wide_to_narrow(text); dstream<<"Changing text of a sign object: " - <sendSignText(m_blockpos, m_id, text); + <sendSignText(m_blockpos, m_id, ntext); } v3s16 m_blockpos; @@ -1040,39 +990,6 @@ struct TextDestSign : public TextDest Client *m_client; }; -struct TextInput -{ - TextDest *dest; - gui::IGUIStaticText* guitext; - /*std::wstring buffer; - bool buffer_accepted;*/ - - TextInput() - { - dest = NULL; - guitext = NULL; - //buffer_accepted = false; - } - - void start(TextDest *a_dest) - { - unFocusGame(); - - guitext = guienv->addStaticText(L"", - core::rect(150,100,550,120), - true, // border? - false, // wordwrap? - NULL); - - guitext->setDrawBackground(true); - - g_text_buffer = L""; - g_text_buffer_accepted = false; - - dest = a_dest; - } -}; - int main(int argc, char *argv[]) { /* @@ -1318,15 +1235,18 @@ int main(int argc, char *argv[]) { snprintf(connect_name, 100, "%s", cmd_args.get("address").c_str()); } - else if(g_settings.get("address") != "" && is_yes(g_settings.get("host_game")) == false) + else if(is_yes(g_settings.get("host_game")) == false) { - std::cout<addStaticText(L"", core::rect(0, 0, 10000, 10000)); - // Pause menu - //pauseMenu = new GUIPauseMenu(guienv, root, -1, device); - - // Inventory menu - /*inventoryMenu = new GUIInventoryMenu(guienv, guiroot, -1, &local_inventory, - &inventory_action_queue);*/ - - //pauseMenu->launch(); - //inventoryMenu->launch(); + // Test the text input system + /*(new GUITextInputMenu(guienv, guiroot, -1, &g_active_menu_count, + NULL))->drop();*/ // First line of debug text gui::IGUIStaticText *guitext = guienv->addStaticText( @@ -1619,9 +1530,6 @@ int main(int argc, char *argv[]) v2u32 screensize = driver->getScreenSize(); core::vector2d displaycenter(screensize.X/2,screensize.Y/2); - /*pauseMenu->resizeGui(); - inventoryMenu->resizeGui();*/ - // Hilight boxes collected during the loop and displayed core::list< core::aabbox3d > hilightboxes; @@ -1652,7 +1560,6 @@ int main(int argc, char *argv[]) Viewing range */ - //updateViewingRange(dtime, &client); updateViewingRange(busytime, &client); /* @@ -1771,24 +1678,10 @@ int main(int argc, char *argv[]) */ g_input->step(dtime); - /* - Special keys - */ - /*if(g_esc_pressed) - { - break; - }*/ - /*if(g_i_pressed) - { - inventoryMenu->setVisible(true); - g_i_pressed = false; - }*/ - /* Player speed control */ - if(g_game_focused) { /*bool a_up, bool a_down, @@ -1810,14 +1703,7 @@ int main(int argc, char *argv[]) ); client.setPlayerControl(control); } - else - { - // Set every key to inactive - PlayerControl control; - client.setPlayerControl(control); - } - //timer1.stop(); /* Process environment */ @@ -1842,11 +1728,7 @@ int main(int argc, char *argv[]) Mouse and camera control */ - if((device->isWindowActive() - && g_game_focused - && noMenuActive() - ) - || random_input) + if((device->isWindowActive() && noMenuActive()) || random_input) { if(!random_input) device->getCursorControl()->setVisible(false); @@ -1940,16 +1822,24 @@ int main(int argc, char *argv[]) if(selected_object->getTypeId() == MAPBLOCKOBJECT_TYPE_SIGN) { dstream<<"Sign object right-clicked"<getBlock()->getPos(), - selected_object->getId(), - &client)); - - if(random_input) + + if(random_input == false) { - g_text_buffer = L"ASD LOL 8)"; - g_text_buffer_accepted = true; + // Get a new text for it + + TextDest *dest = new TextDestSign( + selected_object->getBlock()->getPos(), + selected_object->getId(), + &client); + + SignObject *sign_object = (SignObject*)selected_object; + + std::wstring wtext = + narrow_to_wide(sign_object->getText()); + + (new GUITextInputMenu(guienv, guiroot, -1, + &g_active_menu_count, dest, + wtext))->drop(); } } /* @@ -2328,38 +2218,6 @@ int main(int argc, char *argv[]) delete a; } - if(text_input.guitext != NULL) - { - /*wchar_t temptext[100]; - swprintf(temptext, 100, - SWPRINTF_CHARSTRING, - g_text_buffer.substr(0,99).c_str() - );*/ - text_input.guitext->setText(g_text_buffer.c_str()); - } - - /* - Text input stuff - */ - if(text_input.guitext != NULL && g_text_buffer_accepted) - { - text_input.guitext->remove(); - text_input.guitext = NULL; - - if(text_input.dest != NULL) - { - std::string text = wide_to_narrow(g_text_buffer); - dstream<<"Sending text: "<sendText(text); - delete text_input.dest; - text_input.dest = NULL; - } - - focusGame(); - } - - //guiupdatetimer.stop(); - /* Drawing begins */ diff --git a/src/mapblockobject.h b/src/mapblockobject.h index 30fa797..a65ffd8 100644 --- a/src/mapblockobject.h +++ b/src/mapblockobject.h @@ -531,6 +531,11 @@ public: setBlockChanged(); } + std::string getText() + { + return m_text; + } + void setYaw(f32 yaw) { m_yaw = yaw; diff --git a/src/modalMenu.h b/src/modalMenu.h index 3706d86..e2e8b29 100644 --- a/src/modalMenu.h +++ b/src/modalMenu.h @@ -22,7 +22,11 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "common_irrlicht.h" -//TODO: Change GUIElement private +/* + Remember to drop() the menu after creating, so that it can + remove itself when it wants to. +*/ + class GUIModalMenu : public gui::IGUIElement { public: @@ -50,18 +54,6 @@ public: return (e && (e == this || isMyChild(e))) || m_allow_focus_removal; } - void quitMenu() - { - m_allow_focus_removal = true; - // This removes Environment's grab on us - Environment->removeFocus(this); - this->remove(); - } - - virtual void regenerateGui(v2u32 screensize) = 0; - - virtual void drawMenu() = 0; - void draw() { if(!IsVisible) @@ -78,10 +70,25 @@ public: drawMenu(); } + /* + This should be called when the menu wants to quit + */ + void quitMenu() + { + m_allow_focus_removal = true; + // This removes Environment's grab on us + Environment->removeFocus(this); + this->remove(); + } + + virtual void regenerateGui(v2u32 screensize) = 0; + virtual void drawMenu() = 0; virtual bool OnEvent(const SEvent& event) { return false; }; private: int *m_active_menu_count; + // This might be necessary to expose to the implementation if it + // wants to launch other menus bool m_allow_focus_removal; v2u32 m_screensize_old; }; diff --git a/src/utility.h b/src/utility.h index 4e2e132..bcdcd15 100644 --- a/src/utility.h +++ b/src/utility.h @@ -1009,10 +1009,11 @@ public: // Asks if empty bool getBoolAsk(std::string name, std::string question, bool def) { - std::string s = get(name); - if(s != "") - return is_yes(s); + // If it is in settings + if(m_settings.find(name)) + return getBool(name); + std::string s; char templine[10]; std::cout<