diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 93bd833cd2..b05ca6eaa1 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -33,6 +33,7 @@ source_group(apps\\openmw\\mwinput FILES ${GAMEINPUT} ${GAMEINPUT_HEADER}) set(GAMEGUI_HEADER mwgui/mw_layouts.hpp mwgui/window_manager.hpp + mwgui/console.hpp ) set(GAMEGUI mwgui/window_manager.cpp diff --git a/apps/openmw/mwgui/console.hpp b/apps/openmw/mwgui/console.hpp new file mode 100644 index 0000000000..c4597b3b7e --- /dev/null +++ b/apps/openmw/mwgui/console.hpp @@ -0,0 +1,146 @@ +#ifndef MWGUI_CONSOLE_H +#define MWGUI_CONSOLE_H + +#include +#include +#include + +namespace MWGui +{ + class Console : private OEngine::GUI::Layout + { + public: + MyGUI::EditPtr command; + MyGUI::EditPtr history; + + typedef std::list StringList; + + // History of previous entered commands + StringList command_history; + StringList::iterator current; + std::string editString; + + Console(int w, int h) + : Layout("openmw_console_layout.xml") + { + setCoord(10,10, w-10, h/2); + + getWidget(command, "edit_Command"); + getWidget(history, "list_History"); + + // Set up the command line box + command->eventEditSelectAccept = + newDelegate(this, &Console::acceptCommand); + command->eventKeyButtonPressed = + newDelegate(this, &Console::keyPress); + + // Set up the log window + history->setOverflowToTheLeft(true); + history->setEditStatic(true); + history->setVisibleVScroll(true); + } + + void enable() + { + setVisible(true); + + // Give keyboard focus to the combo box whenever the console is + // turned on + MyGUI::InputManager::getInstance().setKeyFocusWidget(command); + } + + void disable() + { + setVisible(false); + } + + void setFont(const std::string &fntName) + { + history->setFontName(fntName); + command->setFontName(fntName); + } + + void clearHistory() + { + history->setCaption(""); + } + + // Print a message to the console. Messages may contain color + // code, eg. "#FFFFFF this is white". + void print(const std::string &msg) + { history->addText(msg); } + + // These are pre-colored versions that you should use. + + /// Output from successful console command + void printOK(const std::string &msg) + { print("#FF00FF" + msg + "\n"); } + + /// Error message + void printError(const std::string &msg) + { print("#FF2222" + msg + "\n"); } + + private: + + void keyPress(MyGUI::WidgetPtr _sender, + MyGUI::KeyCode key, + MyGUI::Char _char) + { + if(command_history.empty()) return; + + // Traverse history with up and down arrows + if(key == MyGUI::KeyCode::ArrowUp) + { + // If the user was editing a string, store it for later + if(current == command_history.end()) + editString = command->getCaption(); + + if(current != command_history.begin()) + { + current--; + command->setCaption(*current); + } + } + else if(key == MyGUI::KeyCode::ArrowDown) + { + if(current != command_history.end()) + { + current++; + + if(current != command_history.end()) + command->setCaption(*current); + else + // Restore the edit string + command->setCaption(editString); + } + } + } + + void acceptCommand(MyGUI::EditPtr _sender) + { + const std::string &cm = command->getCaption(); + if(cm.empty()) return; + + // Add the command to the history, and set the current pointer to + // the end of the list + command_history.push_back(cm); + current = command_history.end(); + editString.clear(); + + // Log the command + print("#FFFFFF> " + cm + "\n"); + + /* NOTE: This is where the console command should be + handled. + + The console command is in the string 'cm'. Output from the + command should be put back into the console with the + printOK() or printError() functions. + */ + printOK("OK - echoing line " + cm); + + command->setCaption(""); + } + }; +} +#endif diff --git a/apps/openmw/mwgui/window_manager.cpp b/apps/openmw/mwgui/window_manager.cpp index 38757fb6de..d96c93e8eb 100644 --- a/apps/openmw/mwgui/window_manager.cpp +++ b/apps/openmw/mwgui/window_manager.cpp @@ -1,6 +1,8 @@ #include "window_manager.hpp" #include "mw_layouts.hpp" +#include "console.hpp" + #include using namespace MWGui; @@ -17,6 +19,7 @@ WindowManager::WindowManager(MyGUI::Gui *_gui) menu = new MainMenu(w,h); map = new MapWindow(); stats = new StatsWindow(); + console = new Console(w,h); // The HUD is always on hud->setVisible(true); @@ -27,6 +30,7 @@ WindowManager::WindowManager(MyGUI::Gui *_gui) WindowManager::~WindowManager() { + delete console; delete hud; delete map; delete menu; @@ -39,6 +43,7 @@ void WindowManager::updateVisible() map->setVisible(false); menu->setVisible(false); stats->setVisible(false); + console->disable(); // Mouse is visible whenever we're not in game mode gui->setVisiblePointer(isGuiMode()); @@ -56,6 +61,12 @@ void WindowManager::updateVisible() return; } + if(mode == GM_Console) + { + console->enable(); + return; + } + if(mode == GM_Inventory) { // Ah, inventory mode. First, compute the effective set of diff --git a/apps/openmw/mwgui/window_manager.hpp b/apps/openmw/mwgui/window_manager.hpp index 89e08aa69f..f95454aea5 100644 --- a/apps/openmw/mwgui/window_manager.hpp +++ b/apps/openmw/mwgui/window_manager.hpp @@ -21,6 +21,7 @@ namespace MWGui class MapWindow; class MainMenu; class StatsWindow; + class Console; enum GuiMode { @@ -28,6 +29,8 @@ namespace MWGui GM_Inventory, // Inventory mode GM_MainMenu, // Main menu mode + GM_Console, // Console mode + // None of the following are implemented yet GM_Dialogue, // NPC interaction @@ -62,6 +65,7 @@ namespace MWGui MapWindow *map; MainMenu *menu; StatsWindow *stats; + Console *console; MyGUI::Gui *gui; diff --git a/apps/openmw/mwinput/inputmanager.cpp b/apps/openmw/mwinput/inputmanager.cpp index cacedc6a74..f32e207dc2 100644 --- a/apps/openmw/mwinput/inputmanager.cpp +++ b/apps/openmw/mwinput/inputmanager.cpp @@ -32,6 +32,8 @@ namespace MWInput A_Inventory, // Toggle inventory screen + A_Console, // Toggle console screen + A_MoveLeft, // Move player left / right A_MoveRight, A_MoveUp, // Move up / down @@ -117,6 +119,27 @@ namespace MWInput // .. but don't touch any other mode. } + // Toggle console + void toggleConsole() + { + using namespace MWGui; + + GuiMode mode = windows.getMode(); + + // Switch to console mode no matter what mode we are currently + // in, except of course if we are already in console mode + if(mode == GM_Console) + setGuiMode(GM_Game); + else setGuiMode(GM_Console); + } + + // Exit program now button (which is disabled in GUI mode) + void exitNow() + { + if(!windows.isGuiMode()) + exit.exitNow(); + } + public: InputImpl(OEngine::Render::OgreRenderer &_ogre, MWRender::PlayerPos &_player, @@ -139,12 +162,14 @@ namespace MWInput disp = DispatcherPtr(new Dispatcher(A_LAST)); // Bind MW-specific functions - disp->funcs.bind(A_Quit, boost::bind(&ExitListener::exitNow, &exit), + disp->funcs.bind(A_Quit, boost::bind(&InputImpl::exitNow, this), "Quit program"); disp->funcs.bind(A_Screenshot, boost::bind(&InputImpl::screenshot, this), "Screenshot"); disp->funcs.bind(A_Inventory, boost::bind(&InputImpl::toggleInventory, this), "Toggle inventory screen"); + disp->funcs.bind(A_Console, boost::bind(&InputImpl::toggleConsole, this), + "Toggle console"); // Add the exit listener @@ -186,6 +211,7 @@ namespace MWInput disp->bind(A_Quit, KC_ESCAPE); disp->bind(A_Screenshot, KC_SYSRQ); disp->bind(A_Inventory, KC_I); + disp->bind(A_Console, KC_F1); // Key bindings for polled keys diff --git a/old_d_version/gui/cpp_console.cpp b/old_d_version/gui/cpp_console.cpp deleted file mode 100644 index 4e8d1a733d..0000000000 --- a/old_d_version/gui/cpp_console.cpp +++ /dev/null @@ -1,176 +0,0 @@ -/* - OpenMW - The completely unofficial reimplementation of Morrowind - Copyright (C) 2008 Nicolay Korslund - Email: < korslund@gmail.com > - WWW: http://openmw.snaptoad.com/ - - This file (cpp_console.cpp) is part of the OpenMW package. - - OpenMW is distributed as free software: you can redistribute it - and/or modify it under the terms of the GNU General Public License - version 3, as published by the Free Software Foundation. - - 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 - version 3 along with this program. If not, see - http://www.gnu.org/licenses/ . - - */ - -// These are defined in gui/gui.d. At some point later we will just -// use the C++ bindings included with Monster, but these don't cover -// the console stuff yet. -enum - { - CR_OK = 1, // Command was executed - CR_ERROR = 2, // An error occured - CR_MORE = 3, // More input is needed - CR_EMPTY = 4 // The line had no effect - }; - -#include - -extern "C" int32_t console_input(const char* command); -extern "C" char* console_output(); - -class Console : public Layout -{ -public: - MyGUI::EditPtr command; - MyGUI::EditPtr history; - - typedef std::list StringList; - - // History of previous entered commands - StringList command_history; - StringList::iterator current; - Ogre::UTFString editString; - - Console() - : Layout("openmw_console_layout.xml") - { - setCoord(10,10, - mWindow->getWidth()*2/3, mWindow->getHeight()/2); - - getWidget(command, "edit_Command"); - getWidget(history, "list_History"); - - // Set up the command line box - command->eventEditSelectAccept = - newDelegate(this, &Console::acceptCommand); - command->eventKeyButtonPressed = - newDelegate(this, &Console::keyPress); - - // Set up the log window - history->setOverflowToTheLeft(true); - history->setEditStatic(true); - history->setVisibleVScroll(true); - } - - void takeFocus() - { - // Give keyboard focus to the combo box whenever the console is - // turned on - MyGUI::InputManager::getInstance().setKeyFocusWidget(command); - } - - void keyPress(MyGUI::WidgetPtr _sender, - MyGUI::KeyCode key, - MyGUI::Char _char) - { - if(command_history.empty()) return; - - // Traverse history with up and down arrows - if(key == MyGUI::KeyCode::ArrowUp) - { - // If the user was editing a string, store it for later - if(current == command_history.end()) - editString = command->getCaption(); - - if(current != command_history.begin()) - { - current--; - command->setCaption(*current); - } - } - else if(key == MyGUI::KeyCode::ArrowDown) - { - if(current != command_history.end()) - { - current++; - - if(current != command_history.end()) - command->setCaption(*current); - else - // Restore the edit string - command->setCaption(editString); - } - } - } - - - void acceptCommand(MyGUI::EditPtr _sender) - { - const Ogre::UTFString &cm = command->getCaption(); - if(cm.empty()) return; - - // Add the command to the history, and set the current pointer to - // the end of the list - command_history.push_back(cm); - current = command_history.end(); - editString.clear(); - - // Log the command and result - history->addText("#FFFFFF> " + cm + "\n"); - - int res = console_input(cm.asUTF8_c_str()); - Ogre::UTFString out = console_output(); - - if(res == CR_OK) - history->addText("#FF00FF" + out); - else if(res == CR_ERROR) - history->addText("#FF2222" + out); - else if(res == CR_MORE) - history->addText("#1111FF... more input needed\n"); - - exit: - command->setCaption(""); - } -}; - -Console *cons; - -extern "C" void gui_setConsoleFont(const char* fntName) -{ - cons->history->setFontName(fntName); -} - -extern "C" void gui_clearConsole() -{ - cons->history->setCaption(""); -} - -extern "C" void gui_toggleConsole() -{ - if(consoleMode) - { - leaveGui(); - if(cons) - cons->setVisible(false); - } - else - { - enterGui(); - if(cons) - { - cons->setVisible(true); - cons->takeFocus(); - } - } - - consoleMode = !consoleMode; -} diff --git a/old_d_version/gui/cpp_mygui.cpp b/old_d_version/gui/cpp_mygui.cpp deleted file mode 100644 index 42a9c8c30d..0000000000 --- a/old_d_version/gui/cpp_mygui.cpp +++ /dev/null @@ -1,65 +0,0 @@ -bool consoleMode = false; -bool inventoryMode = false; - -void enterGui() -{ - guiMode++; - - if(guiMode == 1) - { - // If we just entered GUI mode, enable the pointer - mGUI->showPointer(); - - // Restore the GUI mouse position. This is a hack because silly - // OIS doesn't allow us to set the mouse position ourselves. - *((OIS::MouseState*)&(mMouse->getMouseState())) = state; - mGUI->injectMouseMove(state.X.abs, state.Y.abs, 0); - } -} - -void leaveGui() -{ - guiMode--; - - if(guiMode < 0) - { - std::cout << "WARNING: guiMode is " << guiMode << "\n"; - guiMode = 0; - } - - // Are we done with all GUI windows? - if(guiMode == 0) - { - // If so, hide the pointer and store the mouse state for later. - mGUI->hidePointer(); - state = mMouse->getMouseState(); - } -} - -extern "C" void gui_toggleGui() -{ - if(inventoryMode) - { - leaveGui(); - if(stats) - stats->setVisible(false); - if(map) - map->setVisible(false); - } - else - { - enterGui(); - if(stats) - stats->setVisible(true); - if(map) - map->setVisible(true); - } - - inventoryMode = !inventoryMode; -} - -extern "C" void gui_setupGUI(int32_t debugOut) -{ - guiMode = 1; - leaveGui(); -}