diff --git a/CMakeLists.txt b/CMakeLists.txt index 6601d64c9c..7d4aa0a30c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,9 +12,15 @@ if(DPKG_PROGRAM) set(MORROWIND_DATA_FILES "/usr/share/games/openmw/data/" CACHE PATH "location of Morrowind data files") set(MORROWIND_RESOURCE_FILES "/usr/share/games/openmw/resources/" CACHE PATH "location of Morrowind data files") else() - set(MORROWIND_DATA_FILES "data" CACHE PATH "location of Morrowind data files") - set(MORROWIND_RESOURCE_FILES "resources" CACHE PATH "location of Morrowind data files") -endif() + if (APPLE) + # set path inside bundle + set(MORROWIND_DATA_FILES "Contents/Resources/data" CACHE PATH "location of Morrowind data files") + set(MORROWIND_RESOURCE_FILES "Contents/Resources/resources" CACHE PATH "location of Morrowind data files") + else() + set(MORROWIND_DATA_FILES "data" CACHE PATH "location of Morrowind data files") + set(MORROWIND_RESOURCE_FILES "resources" CACHE PATH "location of Morrowind data files") + endif(APPLE) +endif(DPKG_PROGRAM) if (WIN32) option(USE_DEBUG_CONSOLE "whether a debug console should be enabled for debug builds, if false debug output is redirected to Visual Studio output" ON) @@ -23,7 +29,6 @@ endif() # We probably support older versions than this. cmake_minimum_required(VERSION 2.6) - # # Pre-built binaries being used? # @@ -239,6 +244,10 @@ if (MSVC10) add_definitions(-DMYGUI_DONT_REPLACE_NULLPTR) endif() +if (APPLE) + set(Boost_USE_STATIC_LIBS ON) +endif (APPLE) + # Dependencies find_package(OGRE REQUIRED) @@ -282,21 +291,19 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${OpenMW_BINARY_DIR}") if (WIN32) configure_file(${OpenMW_SOURCE_DIR}/files/plugins.cfg.win32 "${OpenMW_BINARY_DIR}/plugins.cfg" COPYONLY) -else (WIN32) +endif (WIN32) +if (LINUX) configure_file(${OpenMW_SOURCE_DIR}/files/plugins.cfg.linux "${OpenMW_BINARY_DIR}/plugins.cfg") -endif (WIN32) +endif (LINUX) +if (APPLE) +configure_file(${OpenMW_SOURCE_DIR}/files/plugins.cfg.mac + "${OpenMW_BINARY_DIR}/plugins.cfg") +endif (APPLE) configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg "${OpenMW_BINARY_DIR}/openmw.cfg") -if (APPLE) - set(APPLE_BUNDLE_RESOURCES - ${CMAKE_SOURCE_DIR}/files/openmw.cfg - ${CMAKE_SOURCE_DIR}/files/mac/plugins.cfg - ) -endif (APPLE) - # Compiler settings if (CMAKE_COMPILER_IS_GNUCC) #add_definitions (-Wall -Werror) @@ -306,21 +313,17 @@ endif (CMAKE_COMPILER_IS_GNUCC) # Apple bundling if (APPLE) set(MISC_FILES - ${CMAKE_SOURCE_DIR}/files/openmw.cfg - ${CMAKE_SOURCE_DIR}/files/mac/plugins.cfg - ${CMAKE_SOURCE_DIR}/files/mac/ogre.cfg) -install(TARGETS openmw - BUNDLE DESTINATION . - RUNTIME DESTINATION ../MacOS - COMPONENT Runtime) + ${OpenMW_BINARY_DIR}/openmw.cfg + ${OpenMW_BINARY_DIR}/plugins.cfg) install(FILES ${MISC_FILES} DESTINATION ../MacOS) +install(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION ../Resources) set(CPACK_GENERATOR "Bundle") set(CPACK_BUNDLE_PLIST "${CMAKE_SOURCE_DIR}/files/mac/Info.plist") set(CPACK_BUNDLE_ICON "${CMAKE_SOURCE_DIR}/files/mac/openmw.icns") set(CPACK_BUNDLE_NAME "OpenMW") -set(CPACK_PACKAGE_VERSION "0.07") +set(CPACK_PACKAGE_VERSION "0.10") set(CPACK_PACKAGE_VERSION_MAJOR "0") -set(CPACK_PACKAGE_VERSION_MINOR "07") +set(CPACK_PACKAGE_VERSION_MINOR "10") set(CPACK_PACKAGE_VERSION_PATCH "") include(CPack) diff --git a/README_Mac.md b/README_Mac.md index 3bac3f0c58..194d51e8bc 100644 --- a/README_Mac.md +++ b/README_Mac.md @@ -29,22 +29,28 @@ Getting OpenMW Working ---------------------- 1. Clone this repository. -2. Install `bjam` through MacPorts. -3. Download [boost][] 1.43 and install it with the following command: +2. Note about libs: I prefer not to install them globally (i. e. in /usr/local/), so I installing them in directory in my home directory. If OpenMW sources is in $HOME/path/openmw, I'm using $HOME/path/libs/root as prefix for boost and other libs. + It's useful to create env var for lib install prefix: + $ export OMW_LIB_PREFIX=$HOME/path/libs/root - $ mkdir build && sudo bjam --build-dir=build \ - --layout=versioned --toolset=darwin architecture=i386 \ - address-model=32 --link=shared,static install +3. First of all, set for current terminal some env vars: + $ export CFLAGS="-arch i386" + $ export CXXFLAGS="-arch i386" + $ export LDFLAGS="-arch i386" + All libs will build with correct architecture. + If you close your terminal, you should set env vars again before pcoceeding to next steps! +4. Download [boost][] (tested with 1.45) and install it with the following command: -4. Download [Ogre][] 1.7.1 and build and Xcode project with CMake: + $ cd /path/to/boost/source + $ ./bootstrap.sh --prefix=$OMW_LIB_PREFIX + $ ./bjam --build-dir=build --layout=versioned \ + --toolset=darwin architecture=x86 address-model=32 \ + --link-shared,static --prefix=$OMW_LIB_PREFIX install - $ mdkir build && cd build && \ - BOOST_INCLUDEDIR=/usr/local/include/boost-1_43 \ - BOOST_LIBRARYDIR=/usr/local/lib cmake -G Xcode .. -5. Once the build completes, move `lib/Release/Ogre.framework` into - `/Library/Frameworks`. +5. Download [Ogre][] SDK (tested with 1.7.2) and move `lib/Release/Ogre.framework` into + `Library/Frameworks`. 6. Download [OIS][] and use the XCode project provided in `ois/Mac/XCode-2.2`. Be sure to set your build architecture to @@ -52,20 +58,66 @@ Getting OpenMW Working builds, move `ois/Mac/XCode-2.2/build/Debug/OIS.framework` to `/Library/Frameworks`. -7. Generate the Makefile for OpenMW as follows: - - $ mkdir build && cd build && \ - BOOST_INCLUDEDIR=/usr/local/include/boost-1_43 \ - BOOST_LIBRARYDIR=/usr/local/lib CMAKE_OSX_ARCHITECTURES=i386 \ - cmake .. - -8. Move your Morrowind `Data Files` directory into the root `openmw` - directory with the name `data`. Symlink it into the build directory. - - $ cd build && ln -s ../data data +7. Download [mpg123][] and build it: + $ cd /path/to/mpg123/source + $ ./configure --prefix=$OMW_LIB_PREFIX --disable-debug \ + --disable-dependency-tracking \ + --with-optimization=4 \ + --with-audio=coreaudio \ + --with-default-audio=coreaudio \ + --with-cpu=sse_alone \ + $ make install + +8. Download [libsndfile][] and build it: + $ cd /path/to/libsndfile/source + $ ./configure --prefix=$OMW_LIB_PREFIX \ + --disable-dependency-tracking + $ make install + +7. Generate the Makefile for OpenMW as follows and build OpenMW: + $ mkdir /path/to/openmw/build/dir + $ cd /path/to/open/build/dir + $ CMAKE_OSX_ARCHITECTURES=i386 \ + BOOST_INCLUDEDIR=$OMW_LIB_PREFIX/include/boost-1_45 \ + BOOST_LIBRARYDIR=$OMW_LIB_PREFIX/lib \ + cmake -D SNDFILE_INCLUDE_DIR=$OMW_LIB_PREFIX/include \ + -D SNDFILE_LIBRARY=$OMW_LIB_PREFIX/lib/libsndfile.a \ + -D MPG123_INCLUDE_DIR=$OMW_LIB_PREFIX/include \ + -D MPG123_LIBRARY=$OMW_LIB_PREFIX/lib/libmpg123.a \ + -G "Unix Makefiles" /path/to/openmw/source + $ make + +8. In build directory create directory for game resources: + $ cd /path/to/openmw/build/dir + $ mkdir Contents + $ mkdir Contents/Resources + $ mkdir Contents/Plugins + Copy Ogre plugins from Ogre SDK to Plugins subdir: + $ cp /path/to/ogre/sdk/lib/*.dylib Contents/Plugins + Create symlink to resources subdirectory: + $ ln -s resources Contents/Resources/resources + Create symlinks for *.cfg files: + $ ln -s plugins.cfg Contents/MacOS/plugins.cfg + $ ln -s openmw.cfg Contents/MacOS/openmw.cfg + +9. Move your Morrowind `Data Files` directory into the `Contents/Resources` + with the name `data` or create symlink: + $ ln -s /path/to/morrowind/data/files Contents/Resources/data + +10. From your build directory run: + $ ./openmw + Enjoy! + +11. Optionally you can create .app bundle: + $ make package + But for now you shold manually copy Contents directory from build directory to bundle + (because there is no plugins and resources in generated .app). + [boost]: http://www.boost.org [Ogre]: http://www.ogre3d.org [OIS]: http://wgois.sf.net +[mpg123]: http://www.mpg123.de +[libsndfile]: http://www.mega-nerd.com/libsndfile [official website]: http://openmw.com [Will Thimbleby's Ogre Framework]: http://www.thimbleby.net/ogre/ diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 0f2ac10e57..0fa027f0c6 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -49,6 +49,7 @@ set(GAMEGUI_HEADER mwgui/dialogue.hpp mwgui/dialogue_history.hpp mwgui/window_base.hpp + mwgui/stats_window.hpp ) set(GAMEGUI mwgui/window_manager.cpp @@ -63,6 +64,7 @@ set(GAMEGUI mwgui/dialogue.cpp mwgui/dialogue_history.cpp mwgui/window_base.cpp + mwgui/stats_window.cpp ) source_group(apps\\openmw\\mwgui FILES ${GAMEGUI_HEADER} ${GAMEGUI}) @@ -247,6 +249,10 @@ target_link_libraries(openmw if (APPLE) find_library(CARBON_FRAMEWORK Carbon) target_link_libraries(openmw ${CARBON_FRAMEWORK}) + install(TARGETS openmw + BUNDLE DESTINATION . + RUNTIME DESTINATION ../MacOS + COMPONENT Runtime) endif (APPLE) if(DPKG_PROGRAM) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 4aae0f91db..488490bc69 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -41,6 +41,10 @@ #include +#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE +#include +#endif + #include #include "mwgui/class.hpp" #include "path.hpp" @@ -71,6 +75,11 @@ void OMW::Engine::executeLocalScripts() bool OMW::Engine::frameStarted(const Ogre::FrameEvent& evt) { + if(mShowFPS) + { + mEnvironment.mWindowManager->wmSetFPS(mOgre.getFPS()); + } + if(mUseSound && !(mEnvironment.mSoundManager->isMusicPlaying())) { // Play some good 'ol tunes @@ -196,7 +205,8 @@ bool OMW::Engine::frameStarted(const Ogre::FrameEvent& evt) } OMW::Engine::Engine() - : mDebug (false) + : mShowFPS (false) + , mDebug (false) , mVerboseScripts (false) , mNewGame (false) , mUseSound (true) @@ -360,7 +370,7 @@ void OMW::Engine::go() MWScript::registerExtensions (mExtensions); mEnvironment.mWindowManager = new MWGui::WindowManager(mGuiManager->getGui(), mEnvironment, - mExtensions, mNewGame); + mExtensions, mShowFPS, mNewGame); // Create sound system mEnvironment.mSoundManager = new MWSound::SoundManager(mOgre.getRoot(), diff --git a/apps/openmw/engine.hpp b/apps/openmw/engine.hpp index 8dff580bd1..5e38ab28f6 100644 --- a/apps/openmw/engine.hpp +++ b/apps/openmw/engine.hpp @@ -63,6 +63,7 @@ namespace OMW OEngine::Physic::PhysicEngine* mPhysicEngine; std::string mCellName; std::string mMaster; + bool mShowFPS; bool mDebug; bool mVerboseScripts; bool mNewGame; @@ -121,6 +122,9 @@ namespace OMW /// - Currently OpenMW only supports one master at the same time. void addMaster (const std::string& master); + /// Enable fps counter + void showFPS() { mShowFPS = true; } + /// Enable debug mode: /// - non-exclusive input void enableDebugMode(); diff --git a/apps/openmw/main.cpp b/apps/openmw/main.cpp index 990e6b51ce..4d7e6595cc 100644 --- a/apps/openmw/main.cpp +++ b/apps/openmw/main.cpp @@ -49,6 +49,7 @@ bool parseOptions (int argc, char**argv, OMW::Engine& engine) "set initial cell") ("master", bpo::value()->default_value ("Morrowind"), "master file") + ( "showfps", "show fps counter") ( "debug", "debug mode" ) ( "nosound", "disable all sound" ) ( "script-verbose", "verbose script output" ) @@ -87,6 +88,9 @@ bool parseOptions (int argc, char**argv, OMW::Engine& engine) engine.setCell (variables["start"].as()); engine.addMaster (variables["master"].as()); + if (variables.count ("showfps")) + engine.showFPS(); + if (variables.count ("debug")) engine.enableDebugMode(); @@ -107,6 +111,11 @@ bool parseOptions (int argc, char**argv, OMW::Engine& engine) int main(int argc, char**argv) { +#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE + // set current dir to bundle path + boost::filesystem::path bundlePath = boost::filesystem::path(Ogre::macBundlePath()); + boost::filesystem::current_path(bundlePath); +#endif try { diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index e037d691e2..2e40584320 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -75,7 +75,6 @@ namespace MWClass std::string upperleft[5] = {"", "", "", "", ""}; std::string upperright[5] = {"", "", "", "", ""}; std::string neckandup[5] = {"", "", "","",""}; - std::string empty[6] = {"", "", "", "","", ""}; int numbers = 0; int uppernumbers = 0; int neckNumbers = 0; @@ -110,7 +109,6 @@ namespace MWClass //std::cout << "RACE" << bodyRaceID << "\n"; Ogre::Vector3 pos2 = Ogre::Vector3( 0, .5, 75); - std::string upperarmpath[2] = {npcName + "chest", npcName + "upper arm"}; if (groin){ cellRender.insertMesh("meshes\\" + groin->model, pos2, axis, kOgrePi, npcName + "groin", addresses, numbers); @@ -181,7 +179,7 @@ namespace MWClass upperleft[uppernumbers] = npcName + "upper arm"; upperright[uppernumbers++] = npcName + "upper arm2"; cellRender.scaleMesh(Ogre::Vector3(1, -1, 1), upperleft, uppernumbers); //1 -1 1 - cellRender.rotateMesh(Ogre::Vector3(0, 1, 0), kOgrePiOverTwo, upperleft, uppernumbers); + cellRender.rotateMesh(Ogre::Vector3(0, .1, 0), kOgrePiOverTwo, upperleft, uppernumbers); } if (forearm) diff --git a/apps/openmw/mwgui/birth.cpp b/apps/openmw/mwgui/birth.cpp index 84814d778f..7db93a5087 100644 --- a/apps/openmw/mwgui/birth.cpp +++ b/apps/openmw/mwgui/birth.cpp @@ -1,6 +1,4 @@ #include "birth.hpp" -#include "../mwworld/environment.hpp" -#include "../mwworld/world.hpp" #include "window_manager.hpp" #include "widgets.hpp" #include "components/esm_store/store.hpp" @@ -11,8 +9,8 @@ using namespace MWGui; using namespace Widgets; -BirthDialog::BirthDialog(MWWorld::Environment& environment) - : WindowBase("openmw_chargen_birth_layout.xml", environment) +BirthDialog::BirthDialog(WindowManager& parWindowManager) + : WindowBase("openmw_chargen_birth_layout.xml", parWindowManager) { // Centre dialog center(); @@ -94,7 +92,7 @@ void BirthDialog::setBirthId(const std::string &birthId) void BirthDialog::onOkClicked(MyGUI::Widget* _sender) { - eventDone(); + eventDone(this); } void BirthDialog::onBackClicked(MyGUI::Widget* _sender) @@ -121,7 +119,7 @@ void BirthDialog::updateBirths() { birthList->removeAllItems(); - ESMS::ESMStore &store = environment.mWorld->getStore(); + ESMS::ESMStore &store = mWindowManager.getStore(); ESMS::RecListT::MapType::const_iterator it = store.birthSigns.list.begin(); ESMS::RecListT::MapType::const_iterator end = store.birthSigns.list.end(); @@ -151,7 +149,7 @@ void BirthDialog::updateSpells() const int lineHeight = 18; MyGUI::IntCoord coord(0, 0, spellArea->getWidth(), 18); - ESMS::ESMStore &store = environment.mWorld->getStore(); + ESMS::ESMStore &store = mWindowManager.getStore(); const ESM::BirthSign *birth = store.birthSigns.find(currentBirthId); std::string texturePath = std::string("textures\\") + birth->texture; @@ -191,7 +189,7 @@ void BirthDialog::updateSpells() if (!categories[category].spells.empty()) { MyGUI::StaticTextPtr label = spellArea->createWidget("SandBrightText", coord, MyGUI::Align::Default, std::string("Label")); - label->setCaption(environment.mWindowManager->getGameSettingString(categories[category].label, "")); + label->setCaption(mWindowManager.getGameSettingString(categories[category].label, "")); spellItems.push_back(label); coord.top += lineHeight; @@ -200,7 +198,7 @@ void BirthDialog::updateSpells() { const std::string &spellId = *it; spellWidget = spellArea->createWidget("MW_StatName", coord, MyGUI::Align::Default, std::string("Spell") + boost::lexical_cast(i)); - spellWidget->setEnvironment(&environment); + spellWidget->setWindowManager(&mWindowManager); spellWidget->setSpellId(spellId); spellItems.push_back(spellWidget); diff --git a/apps/openmw/mwgui/birth.hpp b/apps/openmw/mwgui/birth.hpp index 5a8d11b7e8..a55a774a5b 100644 --- a/apps/openmw/mwgui/birth.hpp +++ b/apps/openmw/mwgui/birth.hpp @@ -3,11 +3,6 @@ #include "window_base.hpp" -namespace MWWorld -{ - class Environment; -} - /* This file contains the dialog for choosing a birth sign. Layout is defined by resources/mygui/openmw_chargen_race_layout.xml. @@ -17,10 +12,12 @@ namespace MWGui { using namespace MyGUI; + class WindowManager; + class BirthDialog : public WindowBase { public: - BirthDialog(MWWorld::Environment& environment); + BirthDialog(WindowManager& parWindowManager); enum Gender { @@ -42,11 +39,6 @@ namespace MWGui */ EventHandle_Void eventBack; - /** Event : Dialog finished, OK button clicked.\n - signature : void method()\n - */ - EventHandle_Void eventDone; - protected: void onSelectBirth(MyGUI::List* _sender, size_t _index); diff --git a/apps/openmw/mwgui/class.cpp b/apps/openmw/mwgui/class.cpp index d4ab74a98b..01516cfe25 100644 --- a/apps/openmw/mwgui/class.cpp +++ b/apps/openmw/mwgui/class.cpp @@ -1,6 +1,4 @@ #include "class.hpp" -#include "../mwworld/environment.hpp" -#include "../mwworld/world.hpp" #include "window_manager.hpp" #include "components/esm_store/store.hpp" @@ -17,14 +15,13 @@ using namespace MWGui; /* GenerateClassResultDialog */ -GenerateClassResultDialog::GenerateClassResultDialog(MWWorld::Environment& environment) - : WindowBase("openmw_chargen_generate_class_result_layout.xml", environment) +GenerateClassResultDialog::GenerateClassResultDialog(WindowManager& parWindowManager) + : WindowBase("openmw_chargen_generate_class_result_layout.xml", parWindowManager) { // Centre dialog center(); - WindowManager *wm = environment.mWindowManager; - setText("ReflectT", wm->getGameSettingString("sMessageQuestionAnswer1", "")); + setText("ReflectT", mWindowManager.getGameSettingString("sMessageQuestionAnswer1", "")); getWidget(classImage, "ClassImage"); getWidget(className, "ClassName"); @@ -53,7 +50,7 @@ void GenerateClassResultDialog::setClassId(const std::string &classId) { currentClassId = classId; classImage->setImageTexture(std::string("textures\\levelup\\") + currentClassId + ".dds"); - ESMS::ESMStore &store = environment.mWorld->getStore(); + ESMS::ESMStore &store = mWindowManager.getStore(); className->setCaption(store.classes.find(currentClassId)->name); } @@ -61,7 +58,7 @@ void GenerateClassResultDialog::setClassId(const std::string &classId) void GenerateClassResultDialog::onOkClicked(MyGUI::Widget* _sender) { - eventDone(); + eventDone(this); } void GenerateClassResultDialog::onBackClicked(MyGUI::Widget* _sender) @@ -71,31 +68,30 @@ void GenerateClassResultDialog::onBackClicked(MyGUI::Widget* _sender) /* PickClassDialog */ -PickClassDialog::PickClassDialog(MWWorld::Environment& environment) - : WindowBase("openmw_chargen_class_layout.xml", environment) +PickClassDialog::PickClassDialog(WindowManager& parWindowManager) + : WindowBase("openmw_chargen_class_layout.xml", parWindowManager) { // Centre dialog center(); - WindowManager *wm = environment.mWindowManager; - setText("SpecializationT", wm->getGameSettingString("sChooseClassMenu1", "Specialization")); + setText("SpecializationT", mWindowManager.getGameSettingString("sChooseClassMenu1", "Specialization")); getWidget(specializationName, "SpecializationName"); - setText("FavoriteAttributesT", wm->getGameSettingString("sChooseClassMenu2", "Favorite Attributes:")); + setText("FavoriteAttributesT", mWindowManager.getGameSettingString("sChooseClassMenu2", "Favorite Attributes:")); getWidget(favoriteAttribute[0], "FavoriteAttribute0"); getWidget(favoriteAttribute[1], "FavoriteAttribute1"); - favoriteAttribute[0]->setWindowManager(wm); - favoriteAttribute[1]->setWindowManager(wm); + favoriteAttribute[0]->setWindowManager(&mWindowManager); + favoriteAttribute[1]->setWindowManager(&mWindowManager); - setText("MajorSkillT", wm->getGameSettingString("sChooseClassMenu3", "Major Skills:")); - setText("MinorSkillT", wm->getGameSettingString("sChooseClassMenu4", "Minor Skills:")); + setText("MajorSkillT", mWindowManager.getGameSettingString("sChooseClassMenu3", "Major Skills:")); + setText("MinorSkillT", mWindowManager.getGameSettingString("sChooseClassMenu4", "Minor Skills:")); for(int i = 0; i < 5; i++) { char theIndex = '0'+i; getWidget(majorSkill[i], std::string("MajorSkill").append(1, theIndex)); getWidget(minorSkill[i], std::string("MinorSkill").append(1, theIndex)); - majorSkill[i]->setWindowManager(wm); - minorSkill[i]->setWindowManager(wm); + majorSkill[i]->setWindowManager(&mWindowManager); + minorSkill[i]->setWindowManager(&mWindowManager); } getWidget(classList, "ClassList"); @@ -173,7 +169,7 @@ void PickClassDialog::setClassId(const std::string &classId) void PickClassDialog::onOkClicked(MyGUI::Widget* _sender) { - eventDone(); + eventDone(this); } void PickClassDialog::onBackClicked(MyGUI::Widget* _sender) @@ -200,7 +196,7 @@ void PickClassDialog::updateClasses() { classList->removeAllItems(); - ESMS::ESMStore &store = environment.mWorld->getStore(); + ESMS::ESMStore &store = mWindowManager.getStore(); ESMS::RecListT::MapType::const_iterator it = store.classes.list.begin(); ESMS::RecListT::MapType::const_iterator end = store.classes.list.end(); @@ -224,8 +220,7 @@ void PickClassDialog::updateStats() { if (currentClassId.empty()) return; - WindowManager *wm = environment.mWindowManager; - ESMS::ESMStore &store = environment.mWorld->getStore(); + ESMS::ESMStore &store = mWindowManager.getStore(); const ESM::Class *klass = store.classes.search(currentClassId); if (!klass) return; @@ -237,7 +232,7 @@ void PickClassDialog::updateStats() "sSpecializationMagic", "sSpecializationStealth" }; - specializationName->setCaption(wm->getGameSettingString(specIds[specialization], specIds[specialization])); + specializationName->setCaption(mWindowManager.getGameSettingString(specIds[specialization], specIds[specialization])); favoriteAttribute[0]->setAttributeId(klass->data.attribute[0]); favoriteAttribute[1]->setAttributeId(klass->data.attribute[1]); @@ -283,8 +278,8 @@ void InfoBoxDialog::layoutVertically(MyGUI::WidgetPtr widget, int margin) widget->setSize(width, pos); } -InfoBoxDialog::InfoBoxDialog(MWWorld::Environment& environment) - : WindowBase("openmw_infobox_layout.xml", environment) +InfoBoxDialog::InfoBoxDialog(WindowManager& parWindowManager) + : WindowBase("openmw_infobox_layout.xml", parWindowManager) , currentButton(-1) { getWidget(textBox, "TextBox"); @@ -358,7 +353,7 @@ void InfoBoxDialog::onButtonClicked(MyGUI::WidgetPtr _sender) if (*it == _sender) { currentButton = i; - eventButtonSelected(_sender, i); + eventButtonSelected(i); return; } ++i; @@ -367,23 +362,22 @@ void InfoBoxDialog::onButtonClicked(MyGUI::WidgetPtr _sender) /* ClassChoiceDialog */ -ClassChoiceDialog::ClassChoiceDialog(MWWorld::Environment& environment) - : InfoBoxDialog(environment) +ClassChoiceDialog::ClassChoiceDialog(WindowManager& parWindowManager) + : InfoBoxDialog(parWindowManager) { - WindowManager *mw = environment.mWindowManager; setText(""); ButtonList buttons; - buttons.push_back(mw->getGameSettingString("sClassChoiceMenu1", "")); - buttons.push_back(mw->getGameSettingString("sClassChoiceMenu2", "")); - buttons.push_back(mw->getGameSettingString("sClassChoiceMenu3", "")); - buttons.push_back(mw->getGameSettingString("sBack", "")); + buttons.push_back(mWindowManager.getGameSettingString("sClassChoiceMenu1", "")); + buttons.push_back(mWindowManager.getGameSettingString("sClassChoiceMenu2", "")); + buttons.push_back(mWindowManager.getGameSettingString("sClassChoiceMenu3", "")); + buttons.push_back(mWindowManager.getGameSettingString("sBack", "")); setButtons(buttons); } /* CreateClassDialog */ -CreateClassDialog::CreateClassDialog(MWWorld::Environment& environment) - : WindowBase("openmw_chargen_create_class_layout.xml", environment) +CreateClassDialog::CreateClassDialog(WindowManager& parWindowManager) + : WindowBase("openmw_chargen_create_class_layout.xml", parWindowManager) , specDialog(nullptr) , attribDialog(nullptr) , skillDialog(nullptr) @@ -392,22 +386,21 @@ CreateClassDialog::CreateClassDialog(MWWorld::Environment& environment) // Centre dialog center(); - WindowManager *wm = environment.mWindowManager; - setText("SpecializationT", wm->getGameSettingString("sChooseClassMenu1", "Specialization")); + setText("SpecializationT", mWindowManager.getGameSettingString("sChooseClassMenu1", "Specialization")); getWidget(specializationName, "SpecializationName"); - specializationName->setCaption(wm->getGameSettingString(ESM::Class::gmstSpecializationIds[ESM::Class::Combat], "")); + specializationName->setCaption(mWindowManager.getGameSettingString(ESM::Class::gmstSpecializationIds[ESM::Class::Combat], "")); specializationName->eventMouseButtonClick = MyGUI::newDelegate(this, &CreateClassDialog::onSpecializationClicked); - setText("FavoriteAttributesT", wm->getGameSettingString("sChooseClassMenu2", "Favorite Attributes:")); + setText("FavoriteAttributesT", mWindowManager.getGameSettingString("sChooseClassMenu2", "Favorite Attributes:")); getWidget(favoriteAttribute0, "FavoriteAttribute0"); getWidget(favoriteAttribute1, "FavoriteAttribute1"); - favoriteAttribute0->setWindowManager(wm); - favoriteAttribute1->setWindowManager(wm); + favoriteAttribute0->setWindowManager(&mWindowManager); + favoriteAttribute1->setWindowManager(&mWindowManager); favoriteAttribute0->eventClicked = MyGUI::newDelegate(this, &CreateClassDialog::onAttributeClicked); favoriteAttribute1->eventClicked = MyGUI::newDelegate(this, &CreateClassDialog::onAttributeClicked); - setText("MajorSkillT", wm->getGameSettingString("sSkillClassMajor", "")); - setText("MinorSkillT", wm->getGameSettingString("sSkillClassMinor", "")); + setText("MajorSkillT", mWindowManager.getGameSettingString("sSkillClassMajor", "")); + setText("MinorSkillT", mWindowManager.getGameSettingString("sSkillClassMinor", "")); for(int i = 0; i < 5; i++) { char theIndex = '0'+i; @@ -420,11 +413,11 @@ CreateClassDialog::CreateClassDialog(MWWorld::Environment& environment) std::vector::const_iterator end = skills.end(); for (std::vector::const_iterator it = skills.begin(); it != end; ++it) { - (*it)->setWindowManager(wm); + (*it)->setWindowManager(&mWindowManager); (*it)->eventClicked = MyGUI::newDelegate(this, &CreateClassDialog::onSkillClicked); } - setText("LabelT", wm->getGameSettingString("sName", "")); + setText("LabelT", mWindowManager.getGameSettingString("sName", "")); getWidget(editName, "EditName"); // Make sure the edit box has focus @@ -566,7 +559,7 @@ void CreateClassDialog::onSpecializationClicked(MyGUI::WidgetPtr _sender) { if (specDialog) delete specDialog; - specDialog = new SelectSpecializationDialog(environment, environment.mWindowManager->getGui()->getViewSize()); + specDialog = new SelectSpecializationDialog(mWindowManager); specDialog->eventCancel = MyGUI::newDelegate(this, &CreateClassDialog::onDialogCancel); specDialog->eventItemSelected = MyGUI::newDelegate(this, &CreateClassDialog::onSpecializationSelected); specDialog->setVisible(true); @@ -575,7 +568,7 @@ void CreateClassDialog::onSpecializationClicked(MyGUI::WidgetPtr _sender) void CreateClassDialog::onSpecializationSelected() { specializationId = specDialog->getSpecializationId(); - specializationName->setCaption(environment.mWindowManager->getGameSettingString(ESM::Class::gmstSpecializationIds[specializationId], "")); + specializationName->setCaption(mWindowManager.getGameSettingString(ESM::Class::gmstSpecializationIds[specializationId], "")); specDialog->setVisible(false); } @@ -583,7 +576,7 @@ void CreateClassDialog::onAttributeClicked(Widgets::MWAttributePtr _sender) { if (attribDialog) delete attribDialog; - attribDialog = new SelectAttributeDialog(environment, environment.mWindowManager->getGui()->getViewSize()); + attribDialog = new SelectAttributeDialog(mWindowManager); attribDialog->setAffectedWidget(_sender); attribDialog->eventCancel = MyGUI::newDelegate(this, &CreateClassDialog::onDialogCancel); attribDialog->eventItemSelected = MyGUI::newDelegate(this, &CreateClassDialog::onAttributeSelected); @@ -612,7 +605,7 @@ void CreateClassDialog::onSkillClicked(Widgets::MWSkillPtr _sender) { if (skillDialog) delete skillDialog; - skillDialog = new SelectSkillDialog(environment, environment.mWindowManager->getGui()->getViewSize()); + skillDialog = new SelectSkillDialog(mWindowManager); skillDialog->setAffectedWidget(_sender); skillDialog->eventCancel = MyGUI::newDelegate(this, &CreateClassDialog::onDialogCancel); skillDialog->eventItemSelected = MyGUI::newDelegate(this, &CreateClassDialog::onSkillSelected); @@ -643,21 +636,21 @@ void CreateClassDialog::onSkillSelected() void CreateClassDialog::onDescriptionClicked(MyGUI::Widget* _sender) { - descDialog = new DescriptionDialog(environment, environment.mWindowManager->getGui()->getViewSize()); + descDialog = new DescriptionDialog(mWindowManager); descDialog->setTextInput(description); descDialog->eventDone = MyGUI::newDelegate(this, &CreateClassDialog::onDescriptionEntered); descDialog->setVisible(true); } -void CreateClassDialog::onDescriptionEntered() +void CreateClassDialog::onDescriptionEntered(WindowBase* parWindow) { description = descDialog->getTextInput(); - environment.mWindowManager->removeDialog(descDialog); + mWindowManager.removeDialog(descDialog); } void CreateClassDialog::onOkClicked(MyGUI::Widget* _sender) { - eventDone(); + eventDone(this); } void CreateClassDialog::onBackClicked(MyGUI::Widget* _sender) @@ -667,31 +660,29 @@ void CreateClassDialog::onBackClicked(MyGUI::Widget* _sender) /* SelectSpecializationDialog */ -SelectSpecializationDialog::SelectSpecializationDialog(MWWorld::Environment& environment, MyGUI::IntSize gameWindowSize) - : WindowBase("openmw_chargen_select_specialization_layout.xml", environment) +SelectSpecializationDialog::SelectSpecializationDialog(WindowManager& parWindowManager) + : WindowBase("openmw_chargen_select_specialization_layout.xml", parWindowManager) { // Centre dialog center(); - WindowManager *wm = environment.mWindowManager; - - setText("LabelT", wm->getGameSettingString("sSpecializationMenu1", "")); + setText("LabelT", mWindowManager.getGameSettingString("sSpecializationMenu1", "")); getWidget(specialization0, "Specialization0"); getWidget(specialization1, "Specialization1"); getWidget(specialization2, "Specialization2"); - specialization0->setCaption(wm->getGameSettingString(ESM::Class::gmstSpecializationIds[ESM::Class::Combat], "")); + specialization0->setCaption(mWindowManager.getGameSettingString(ESM::Class::gmstSpecializationIds[ESM::Class::Combat], "")); specialization0->eventMouseButtonClick = MyGUI::newDelegate(this, &SelectSpecializationDialog::onSpecializationClicked); - specialization1->setCaption(wm->getGameSettingString(ESM::Class::gmstSpecializationIds[ESM::Class::Magic], "")); + specialization1->setCaption(mWindowManager.getGameSettingString(ESM::Class::gmstSpecializationIds[ESM::Class::Magic], "")); specialization1->eventMouseButtonClick = MyGUI::newDelegate(this, &SelectSpecializationDialog::onSpecializationClicked); - specialization2->setCaption(wm->getGameSettingString(ESM::Class::gmstSpecializationIds[ESM::Class::Stealth], "")); + specialization2->setCaption(mWindowManager.getGameSettingString(ESM::Class::gmstSpecializationIds[ESM::Class::Stealth], "")); specialization2->eventMouseButtonClick = MyGUI::newDelegate(this, &SelectSpecializationDialog::onSpecializationClicked); specializationId = ESM::Class::Combat; // TODO: These buttons should be managed by a Dialog class MyGUI::ButtonPtr cancelButton; getWidget(cancelButton, "CancelButton"); - cancelButton->setCaption(wm->getGameSettingString("sCancel", "")); + cancelButton->setCaption(mWindowManager.getGameSettingString("sCancel", "")); cancelButton->eventMouseButtonClick = MyGUI::newDelegate(this, &SelectSpecializationDialog::onCancelClicked); } @@ -718,15 +709,13 @@ void SelectSpecializationDialog::onCancelClicked(MyGUI::Widget* _sender) /* SelectAttributeDialog */ -SelectAttributeDialog::SelectAttributeDialog(MWWorld::Environment& environment, MyGUI::IntSize gameWindowSize) - : WindowBase("openmw_chargen_select_attribute_layout.xml", environment) +SelectAttributeDialog::SelectAttributeDialog(WindowManager& parWindowManager) + : WindowBase("openmw_chargen_select_attribute_layout.xml", parWindowManager) { // Centre dialog center(); - WindowManager *wm = environment.mWindowManager; - - setText("LabelT", wm->getGameSettingString("sAttributesMenu1", "")); + setText("LabelT", mWindowManager.getGameSettingString("sAttributesMenu1", "")); for (int i = 0; i < 8; ++i) { @@ -734,7 +723,7 @@ SelectAttributeDialog::SelectAttributeDialog(MWWorld::Environment& environment, char theIndex = '0'+i; getWidget(attribute, std::string("Attribute").append(1, theIndex)); - attribute->setWindowManager(wm); + attribute->setWindowManager(&parWindowManager); attribute->setAttributeId(ESM::Attribute::attributeIds[i]); attribute->eventClicked = MyGUI::newDelegate(this, &SelectAttributeDialog::onAttributeClicked); } @@ -742,7 +731,7 @@ SelectAttributeDialog::SelectAttributeDialog(MWWorld::Environment& environment, // TODO: These buttons should be managed by a Dialog class MyGUI::ButtonPtr cancelButton; getWidget(cancelButton, "CancelButton"); - cancelButton->setCaption(wm->getGameSettingString("sCancel", "")); + cancelButton->setCaption(mWindowManager.getGameSettingString("sCancel", "")); cancelButton->eventMouseButtonClick = MyGUI::newDelegate(this, &SelectAttributeDialog::onCancelClicked); } @@ -763,18 +752,16 @@ void SelectAttributeDialog::onCancelClicked(MyGUI::Widget* _sender) /* SelectSkillDialog */ -SelectSkillDialog::SelectSkillDialog(MWWorld::Environment& environment, MyGUI::IntSize gameWindowSize) - : WindowBase("openmw_chargen_select_skill_layout.xml", environment) +SelectSkillDialog::SelectSkillDialog(WindowManager& parWindowManager) + : WindowBase("openmw_chargen_select_skill_layout.xml", parWindowManager) { // Centre dialog center(); - WindowManager *wm = environment.mWindowManager; - - setText("LabelT", wm->getGameSettingString("sSkillsMenu1", "")); - setText("CombatLabelT", wm->getGameSettingString("sSpecializationCombat", "")); - setText("MagicLabelT", wm->getGameSettingString("sSpecializationMagic", "")); - setText("StealthLabelT", wm->getGameSettingString("sSpecializationStealth", "")); + setText("LabelT", mWindowManager.getGameSettingString("sSkillsMenu1", "")); + setText("CombatLabelT", mWindowManager.getGameSettingString("sSpecializationCombat", "")); + setText("MagicLabelT", mWindowManager.getGameSettingString("sSpecializationMagic", "")); + setText("StealthLabelT", mWindowManager.getGameSettingString("sSpecializationStealth", "")); for(int i = 0; i < 9; i++) { @@ -824,7 +811,7 @@ SelectSkillDialog::SelectSkillDialog(MWWorld::Environment& environment, MyGUI::I { for (int i = 0; i < 9; ++i) { - skills[spec][i].widget->setWindowManager(wm); + skills[spec][i].widget->setWindowManager(&mWindowManager); skills[spec][i].widget->setSkillId(skills[spec][i].skillId); skills[spec][i].widget->eventClicked = MyGUI::newDelegate(this, &SelectSkillDialog::onSkillClicked); } @@ -833,7 +820,7 @@ SelectSkillDialog::SelectSkillDialog(MWWorld::Environment& environment, MyGUI::I // TODO: These buttons should be managed by a Dialog class MyGUI::ButtonPtr cancelButton; getWidget(cancelButton, "CancelButton"); - cancelButton->setCaption(wm->getGameSettingString("sCancel", "")); + cancelButton->setCaption(mWindowManager.getGameSettingString("sCancel", "")); cancelButton->eventMouseButtonClick = MyGUI::newDelegate(this, &SelectSkillDialog::onCancelClicked); } @@ -852,8 +839,8 @@ void SelectSkillDialog::onCancelClicked(MyGUI::Widget* _sender) /* DescriptionDialog */ -DescriptionDialog::DescriptionDialog(MWWorld::Environment& environment, MyGUI::IntSize gameWindowSize) - : WindowBase("openmw_chargen_class_description_layout.xml", environment) +DescriptionDialog::DescriptionDialog(WindowManager& parWindowManager) + : WindowBase("openmw_chargen_class_description_layout.xml", parWindowManager) { // Centre dialog center(); @@ -864,7 +851,7 @@ DescriptionDialog::DescriptionDialog(MWWorld::Environment& environment, MyGUI::I MyGUI::ButtonPtr okButton; getWidget(okButton, "OKButton"); okButton->eventMouseButtonClick = MyGUI::newDelegate(this, &DescriptionDialog::onOkClicked); - okButton->setCaption(environment.mWindowManager->getGameSettingString("sInputMenu1", "")); + okButton->setCaption(mWindowManager.getGameSettingString("sInputMenu1", "")); // Make sure the edit box has focus MyGUI::InputManager::getInstance().setKeyFocusWidget(textEdit); @@ -874,5 +861,5 @@ DescriptionDialog::DescriptionDialog(MWWorld::Environment& environment, MyGUI::I void DescriptionDialog::onOkClicked(MyGUI::Widget* _sender) { - eventDone(); + eventDone(this); } diff --git a/apps/openmw/mwgui/class.hpp b/apps/openmw/mwgui/class.hpp index d2a1987378..5f1734b195 100644 --- a/apps/openmw/mwgui/class.hpp +++ b/apps/openmw/mwgui/class.hpp @@ -5,11 +5,6 @@ #include "widgets.hpp" #include "window_base.hpp" -namespace MWWorld -{ - class Environment; -} - /* This file contains the dialogs for choosing a class. Layout is defined by resources/mygui/openmw_chargen_class_layout.xml. @@ -19,10 +14,12 @@ namespace MWGui { using namespace MyGUI; + class WindowManager; + class InfoBoxDialog : public WindowBase { public: - InfoBoxDialog(MWWorld::Environment& environment); + InfoBoxDialog(WindowManager& parWindowManager); typedef std::vector ButtonList; @@ -34,12 +31,12 @@ namespace MWGui int getChosenButton() const; // Events - typedef delegates::CDelegate2 EventHandle_WidgetInt; + typedef delegates::CDelegate1 EventHandle_Int; /** Event : Button was clicked.\n signature : void method(MyGUI::WidgetPtr widget, int index)\n */ - EventHandle_WidgetInt eventButtonSelected; + EventHandle_Int eventButtonSelected; protected: void onButtonClicked(MyGUI::WidgetPtr _sender); @@ -67,13 +64,13 @@ namespace MWGui Class_Create = 2, Class_Back = 3 }; - ClassChoiceDialog(MWWorld::Environment& environment); + ClassChoiceDialog(WindowManager& parWindowManager); }; class GenerateClassResultDialog : public WindowBase { public: - GenerateClassResultDialog(MWWorld::Environment& environment); + GenerateClassResultDialog(WindowManager& parWindowManager); std::string getClassId() const; void setClassId(const std::string &classId); @@ -88,11 +85,6 @@ namespace MWGui */ EventHandle_Void eventBack; - /** Event : Dialog finished, OK button clicked.\n - signature : void method()\n - */ - EventHandle_Void eventDone; - protected: void onOkClicked(MyGUI::Widget* _sender); void onBackClicked(MyGUI::Widget* _sender); @@ -107,7 +99,7 @@ namespace MWGui class PickClassDialog : public WindowBase { public: - PickClassDialog(MWWorld::Environment& environment); + PickClassDialog(WindowManager& parWindowManager); const std::string &getClassId() const { return currentClassId; } void setClassId(const std::string &classId); @@ -123,11 +115,6 @@ namespace MWGui */ EventHandle_Void eventBack; - /** Event : Dialog finished, OK button clicked.\n - signature : void method()\n - */ - EventHandle_Void eventDone; - protected: void onSelectClass(MyGUI::List* _sender, size_t _index); @@ -151,7 +138,7 @@ namespace MWGui class SelectSpecializationDialog : public WindowBase { public: - SelectSpecializationDialog(MWWorld::Environment& environment, MyGUI::IntSize gameWindowSize); + SelectSpecializationDialog(WindowManager& parWindowManager); ESM::Class::Specialization getSpecializationId() const { return specializationId; } @@ -181,7 +168,7 @@ namespace MWGui class SelectAttributeDialog : public WindowBase { public: - SelectAttributeDialog(MWWorld::Environment& environment, MyGUI::IntSize gameWindowSize); + SelectAttributeDialog(WindowManager& parWindowManager); ESM::Attribute::AttributeID getAttributeId() const { return attributeId; } Widgets::MWAttributePtr getAffectedWidget() const { return affectedWidget; } @@ -213,7 +200,7 @@ namespace MWGui class SelectSkillDialog : public WindowBase { public: - SelectSkillDialog(MWWorld::Environment& environment, MyGUI::IntSize gameWindowSize); + SelectSkillDialog(WindowManager& parWindowManager); ESM::Skill::SkillEnum getSkillId() const { return skillId; } Widgets::MWSkillPtr getAffectedWidget() const { return affectedWidget; } @@ -248,19 +235,11 @@ namespace MWGui class DescriptionDialog : public WindowBase { public: - DescriptionDialog(MWWorld::Environment& environment, MyGUI::IntSize gameWindowSize); + DescriptionDialog(WindowManager& parWindowManager); std::string getTextInput() const { return textEdit ? textEdit->getOnlyText() : ""; } void setTextInput(const std::string &text) { if (textEdit) textEdit->setOnlyText(text); } - // Events - typedef delegates::CDelegate0 EventHandle_Void; - - /** Event : Dialog finished, OK button clicked.\n - signature : void method()\n - */ - EventHandle_Void eventDone; - protected: void onOkClicked(MyGUI::Widget* _sender); @@ -271,7 +250,7 @@ namespace MWGui class CreateClassDialog : public WindowBase { public: - CreateClassDialog(MWWorld::Environment& environment); + CreateClassDialog(WindowManager& parWindowManager); virtual ~CreateClassDialog(); std::string getName() const; @@ -292,11 +271,6 @@ namespace MWGui */ EventHandle_Void eventBack; - /** Event : Dialog finished, OK button clicked.\n - signature : void method()\n - */ - EventHandle_Void eventDone; - protected: void onOkClicked(MyGUI::Widget* _sender); void onBackClicked(MyGUI::Widget* _sender); @@ -308,7 +282,7 @@ namespace MWGui void onSkillClicked(Widgets::MWSkillPtr _sender); void onSkillSelected(); void onDescriptionClicked(MyGUI::Widget* _sender); - void onDescriptionEntered(); + void onDescriptionEntered(WindowBase* parWindow); void onDialogCancel(); private: diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp index fe43cabc9d..e48c142aaf 100644 --- a/apps/openmw/mwgui/dialogue.cpp +++ b/apps/openmw/mwgui/dialogue.cpp @@ -1,7 +1,5 @@ #include "dialogue.hpp" #include "dialogue_history.hpp" -#include "../mwworld/environment.hpp" -#include "../mwworld/world.hpp" #include "window_manager.hpp" #include "widgets.hpp" #include "components/esm_store/store.hpp" @@ -16,8 +14,8 @@ using namespace MWGui; using namespace Widgets; -DialogueWindow::DialogueWindow(MWWorld::Environment& environment) - : WindowBase("openmw_dialogue_window_layout.xml", environment) +DialogueWindow::DialogueWindow(WindowManager& parWindowManager) + : WindowBase("openmw_dialogue_window_layout.xml", parWindowManager) { // Centre dialog center(); diff --git a/apps/openmw/mwgui/dialogue.hpp b/apps/openmw/mwgui/dialogue.hpp index 3e4852203e..ddb6f8a4c8 100644 --- a/apps/openmw/mwgui/dialogue.hpp +++ b/apps/openmw/mwgui/dialogue.hpp @@ -4,9 +4,9 @@ #include "window_base.hpp" #include -namespace MWWorld +namespace MWGui { - class Environment; + class WindowManager; } /* @@ -23,7 +23,7 @@ namespace MWGui class DialogueWindow: public WindowBase { public: - DialogueWindow(MWWorld::Environment& environment); + DialogueWindow(WindowManager& parWindowManager); void open(); diff --git a/apps/openmw/mwgui/dialogue_history.cpp b/apps/openmw/mwgui/dialogue_history.cpp index d7a274f7af..aaa559d243 100644 --- a/apps/openmw/mwgui/dialogue_history.cpp +++ b/apps/openmw/mwgui/dialogue_history.cpp @@ -1,6 +1,4 @@ #include "dialogue_history.hpp" -#include "../mwworld/environment.hpp" -#include "../mwworld/world.hpp" #include "window_manager.hpp" #include "widgets.hpp" #include "components/esm_store/store.hpp" diff --git a/apps/openmw/mwgui/layouts.cpp b/apps/openmw/mwgui/layouts.cpp index 73b8d77e85..10740e224a 100644 --- a/apps/openmw/mwgui/layouts.cpp +++ b/apps/openmw/mwgui/layouts.cpp @@ -1,416 +1,126 @@ #include "layouts.hpp" -#include "../mwworld/class.hpp" #include "../mwmechanics/mechanicsmanager.hpp" -#include "../mwgui/window_manager.hpp" +#include "window_manager.hpp" #include #include #include -#include #undef min #undef max using namespace MWGui; -const int StatsWindow::lineHeight = 18; -StatsWindow::StatsWindow (MWWorld::Environment& environment) - : WindowBase("openmw_stats_window_layout.xml", environment) - , lastPos(0) - , reputation(0) - , bounty(0) +HUD::HUD(int width, int height, bool fpsSwitch) + : Layout("openmw_hud_layout.xml") { - setCoord(0,0,498, 342); + setCoord(0,0, width, height); - const char *names[][2] = - { - { "Attrib1", "sAttributeStrength" }, - { "Attrib2", "sAttributeIntelligence" }, - { "Attrib3", "sAttributeWillpower" }, - { "Attrib4", "sAttributeAgility" }, - { "Attrib5", "sAttributeSpeed" }, - { "Attrib6", "sAttributeEndurance" }, - { "Attrib7", "sAttributePersonality" }, - { "Attrib8", "sAttributeLuck" }, - { "Health_str", "sHealth" }, - { "Magicka_str", "sMagic" }, - { "Fatigue_str", "sFatigue" }, - { "Level_str", "sLevel" }, - { "Race_str", "sRace" }, - { "Class_str", "sClass" }, - { 0, 0 } - }; + // Energy bars + getWidget(health, "Health"); + getWidget(magicka, "Magicka"); + getWidget(stamina, "Stamina"); - const ESMS::ESMStore &store = environment.mWorld->getStore(); - for (int i=0; names[i][0]; ++i) - { - setText (names[i][0], store.gameSettings.find (names[i][1])->str); - } + // Item and spell images and status bars + getWidget(weapImage, "WeapImage"); + getWidget(weapStatus, "WeapStatus"); + getWidget(spellImage, "SpellImage"); + getWidget(spellStatus, "SpellStatus"); - getWidget(skillAreaWidget, "Skills"); - getWidget(skillClientWidget, "SkillClient"); - getWidget(skillScrollerWidget, "SkillScroller"); + getWidget(effectBox, "EffectBox"); + getWidget(effect1, "Effect1"); - skillScrollerWidget->eventScrollChangePosition = MyGUI::newDelegate(this, &StatsWindow::onScrollChangePosition); - updateScroller(); + getWidget(minimap, "MiniMap"); + getWidget(compass, "Compass"); - for (int i = 0; i < ESM::Skill::Length; ++i) - { - skillValues.insert(std::make_pair(i, MWMechanics::Stat())); - skillWidgetMap.insert(std::make_pair(i, static_cast (0))); - } + getWidget(crosshair, "Crosshair"); - MyGUI::WindowPtr t = static_cast(mMainWidget); - t->eventWindowChangeCoord = MyGUI::newDelegate(this, &StatsWindow::onWindowResize); -} + getWidget(fpsbox, "FPSBox"); + getWidget(fpscounter, "FPSCounter"); -void StatsWindow::onScrollChangePosition(MyGUI::VScrollPtr scroller, size_t pos) -{ - int diff = lastPos - pos; - // Adjust position of all widget according to difference - if (diff == 0) - return; - lastPos = pos; + fpsbox->setVisible(fpsSwitch); - std::vector::const_iterator end = skillWidgets.end(); - for (std::vector::const_iterator it = skillWidgets.begin(); it != end; ++it) - { - (*it)->setCoord((*it)->getCoord() + MyGUI::IntPoint(0, diff)); - } -} + compass->setImageTexture("textures\\compass.dds"); + crosshair->setImageTexture("textures\\target.dds"); -void StatsWindow::onWindowResize(MyGUI::WidgetPtr window) -{ - updateScroller(); + // These are just demo values, you should replace these with + // real calls from outside the class later. + setWeapIcon("icons\\w\\tx_knife_iron.dds"); + setWeapStatus(90, 100); + setSpellIcon("icons\\s\\b_tx_s_rstor_health.dds"); + setSpellStatus(65, 100); + setEffect("icons\\s\\tx_s_chameleon.dds"); } -void StatsWindow::setBar(const std::string& name, const std::string& tname, int val, int max) +void HUD::setFPS(float fps) { - MyGUI::ProgressPtr pt; - getWidget(pt, name); - pt->setProgressRange(max); - pt->setProgressPosition(val); - - std::stringstream out; - out << val << "/" << max; - setText(tname, out.str().c_str()); + fpscounter->setCaption(boost::lexical_cast((int)fps)); } -void StatsWindow::setPlayerName(const std::string& playerName) + +void HUD::setStats(int h, int hmax, int m, int mmax, int s, int smax) { - mMainWidget->setCaption(playerName); + health->setProgressRange(hmax); + health->setProgressPosition(h); + magicka->setProgressRange(mmax); + magicka->setProgressPosition(m); + stamina->setProgressRange(smax); + stamina->setProgressPosition(s); } -void StatsWindow::setStyledText(MyGUI::StaticTextPtr widget, ColorStyle style, const std::string &value) +void HUD::setWeapIcon(const char *str) { - widget->setCaption(value); - if (style == CS_Super) - widget->setTextColour(MyGUI::Colour(0, 1, 0)); - else if (style == CS_Sub) - widget->setTextColour(MyGUI::Colour(1, 0, 0)); - else - widget->setTextColour(MyGUI::Colour(1, 1, 1)); + weapImage->setImageTexture(str); } -void StatsWindow::setValue (const std::string& id, const MWMechanics::Stat& value) +void HUD::setSpellIcon(const char *str) { - static const char *ids[] = - { - "AttribVal1", "AttribVal2", "AttribVal3", "AttribVal4", "AttribVal5", - "AttribVal6", "AttribVal7", "AttribVal8", - 0 - }; - - for (int i=0; ids[i]; ++i) - if (ids[i]==id) - { - std::ostringstream valueString; - valueString << value.getModified(); - setText (id, valueString.str()); - - if (value.getModified()>value.getBase()) - setTextColor (id, 0, 1, 0); - else if (value.getModified()setImageTexture(str); } -void StatsWindow::setValue (const std::string& id, const MWMechanics::DynamicStat& value) +void HUD::setWeapStatus(int s, int smax) { - static const char *ids[] = - { - "HBar", "MBar", "FBar", - 0 - }; - - for (int i=0; ids[i]; ++i) - if (ids[i]==id) - { - std::string id (ids[i]); - setBar (id, id + "T", value.getCurrent(), value.getModified()); - } + weapStatus->setProgressRange(smax); + weapStatus->setProgressPosition(s); } -void StatsWindow::setValue (const std::string& id, const std::string& value) +void HUD::setSpellStatus(int s, int smax) { - if (id=="name") - setPlayerName (value); - else if (id=="race") - setText ("RaceText", value); - else if (id=="class") - setText ("ClassText", value); + spellStatus->setProgressRange(smax); + spellStatus->setProgressPosition(s); } -void StatsWindow::setValue (const std::string& id, int value) +void HUD::setEffect(const char *img) { - if (id=="level") - { - std::ostringstream text; - text << value; - setText("LevelText", text.str()); - } + effect1->setImageTexture(img); } -void StatsWindow::setValue (const std::string& id, const MWMechanics::Stat& value) +void HUD::setValue(const std::string& id, const MWMechanics::DynamicStat& value) { - static struct {const char *id; ESM::Skill::SkillEnum skillId; } skillMap[] = + static const char *ids[] = { - {"SkillBlock", ESM::Skill::Block}, - {"SkillArmorer", ESM::Skill::Armorer}, - {"SkillMediumArmor", ESM::Skill::MediumArmor}, - {"SkillHeavyArmor", ESM::Skill::HeavyArmor}, - {"SkillBluntWeapon", ESM::Skill::BluntWeapon}, - {"SkillLongBlade", ESM::Skill::LongBlade}, - {"SkillAxe", ESM::Skill::Axe}, - {"SkillSpear", ESM::Skill::Spear}, - {"SkillAthletics", ESM::Skill::Athletics}, - {"SkillEnchant", ESM::Skill::Armorer}, - {"SkillDestruction", ESM::Skill::Destruction}, - {"SkillAlteration", ESM::Skill::Alteration}, - {"SkillIllusion", ESM::Skill::Illusion}, - {"SkillConjuration", ESM::Skill::Conjuration}, - {"SkillMysticism", ESM::Skill::Mysticism}, - {"SkillRestoration", ESM::Skill::Restoration}, - {"SkillAlchemy", ESM::Skill::Alchemy}, - {"SkillUnarmored", ESM::Skill::Unarmored}, - {"SkillSecurity", ESM::Skill::Security}, - {"SkillSneak", ESM::Skill::Sneak}, - {"SkillAcrobatics", ESM::Skill::Acrobatics}, - {"SkillLightArmor", ESM::Skill::LightArmor}, - {"SkillShortBlade", ESM::Skill::ShortBlade}, - {"SkillMarksman", ESM::Skill::Marksman}, - {"SkillMercantile", ESM::Skill::Mercantile}, - {"SkillSpeechcraft", ESM::Skill::Speechcraft}, - {"SkillHandToHand", ESM::Skill::HandToHand}, + "HBar", "MBar", "FBar", 0 }; - for (size_t i = 0; i < sizeof(skillMap)/sizeof(skillMap[0]); ++i) - { - if (skillMap[i].id == id) + + for (int i=0; ids[i]; ++i) + if (ids[i]==id) { - int skillId = skillMap[i].skillId; - skillValues[skillId] = value; - MyGUI::StaticTextPtr widget = skillWidgetMap[skillId]; - if (widget) + switch (i) { - float modified = value.getModified(), base = value.getBase(); - std::string text = boost::lexical_cast(std::floor(modified)); - ColorStyle style = CS_Normal; - if (modified > base) - style = CS_Super; - else if (modified < base) - style = CS_Sub; - - setStyledText(widget, style, text); + case 0: + health->setProgressRange (value.getModified()); + health->setProgressPosition (value.getCurrent()); + break; + case 1: + magicka->setProgressRange (value.getModified()); + magicka->setProgressPosition (value.getCurrent()); + break; + case 2: + stamina->setProgressRange (value.getModified()); + stamina->setProgressPosition (value.getCurrent()); + break; } - break; } - } -} - -void StatsWindow::configureSkills (const std::vector& major, const std::vector& minor) -{ - majorSkills = major; - minorSkills = minor; - - // Update misc skills with the remaining skills not in major or minor - std::set skillSet; - std::copy(major.begin(), major.end(), std::inserter(skillSet, skillSet.begin())); - std::copy(minor.begin(), minor.end(), std::inserter(skillSet, skillSet.begin())); - boost::array::const_iterator end = ESM::Skill::skillIds.end(); - miscSkills.clear(); - for (boost::array::const_iterator it = ESM::Skill::skillIds.begin(); it != end; ++it) - { - int skill = *it; - if (skillSet.find(skill) == skillSet.end()) - miscSkills.push_back(skill); - } -} - -void StatsWindow::setFactions (const std::vector& factions) -{ - this->factions = factions; -} - -void StatsWindow::setBirthSign (const std::string& signId) -{ - birthSignId = signId; -} - -void StatsWindow::addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) -{ - MyGUI::StaticImagePtr separator = skillClientWidget->createWidget("MW_HLine", MyGUI::IntCoord(10, coord1.top, coord1.width + coord2.width - 4, 18), MyGUI::Align::Default); - skillWidgets.push_back(separator); - - coord1.top += separator->getHeight(); - coord2.top += separator->getHeight(); -} - -void StatsWindow::addGroup(const std::string &label, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) -{ - MyGUI::StaticTextPtr groupWidget = skillClientWidget->createWidget("SandBrightText", MyGUI::IntCoord(0, coord1.top, coord1.width + coord2.width, coord1.height), MyGUI::Align::Default); - groupWidget->setCaption(label); - skillWidgets.push_back(groupWidget); - - coord1.top += lineHeight; - coord2.top += lineHeight; -} - -MyGUI::StaticTextPtr StatsWindow::addValueItem(const std::string text, const std::string &value, ColorStyle style, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) -{ - MyGUI::StaticTextPtr skillNameWidget, skillValueWidget; - - skillNameWidget = skillClientWidget->createWidget("SandText", coord1, MyGUI::Align::Default); - skillNameWidget->setCaption(text); - - skillValueWidget = skillClientWidget->createWidget("SandTextRight", coord2, MyGUI::Align::Default); - setStyledText(skillValueWidget, style, value); - - skillWidgets.push_back(skillNameWidget); - skillWidgets.push_back(skillValueWidget); - - coord1.top += lineHeight; - coord2.top += lineHeight; - - return skillValueWidget; -} - -void StatsWindow::addItem(const std::string text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) -{ - MyGUI::StaticTextPtr skillNameWidget; - - skillNameWidget = skillClientWidget->createWidget("SandText", coord1 + MyGUI::IntSize(coord2.width, 0), MyGUI::Align::Default); - skillNameWidget->setCaption(text); - - skillWidgets.push_back(skillNameWidget); - - coord1.top += lineHeight; - coord2.top += lineHeight; -} - -void StatsWindow::addSkills(const SkillList &skills, const std::string &titleId, const std::string &titleDefault, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) -{ - WindowManager *wm = environment.mWindowManager; - - // Add a line separator if there are items above - if (!skillWidgets.empty()) - { - addSeparator(coord1, coord2); - } - - addGroup(wm->getGameSettingString(titleId, titleDefault), coord1, coord2); - - SkillList::const_iterator end = skills.end(); - for (SkillList::const_iterator it = skills.begin(); it != end; ++it) - { - int skillId = *it; - if (skillId < 0 || skillId > ESM::Skill::Length) // Skip unknown skill indexes - continue; - assert(skillId >= 0 && skillId < ESM::Skill::Length); - const std::string &skillNameId = ESMS::Skill::sSkillNameIds[skillId]; - const MWMechanics::Stat &stat = skillValues.find(skillId)->second; - float base = stat.getBase(); - float modified = stat.getModified(); - - ColorStyle style = CS_Normal; - if (modified > base) - style = CS_Super; - else if (modified < base) - style = CS_Sub; - MyGUI::StaticTextPtr widget = addValueItem(wm->getGameSettingString(skillNameId, skillNameId), boost::lexical_cast(static_cast(modified)), style, coord1, coord2); - skillWidgetMap[skillId] = widget; - } -} - -void StatsWindow::updateSkillArea() -{ - for (std::vector::iterator it = skillWidgets.begin(); it != skillWidgets.end(); ++it) - { - MyGUI::Gui::getInstance().destroyWidget(*it); - } - skillWidgets.clear(); - - const int valueSize = 40; - MyGUI::IntCoord coord1(10, 0, skillClientWidget->getWidth() - (10 + valueSize), 18); - MyGUI::IntCoord coord2(coord1.left + coord1.width, coord1.top, valueSize, coord1.height); - - if (!majorSkills.empty()) - addSkills(majorSkills, "sSkillClassMajor", "Major Skills", coord1, coord2); - - if (!minorSkills.empty()) - addSkills(minorSkills, "sSkillClassMinor", "Minor Skills", coord1, coord2); - - if (!miscSkills.empty()) - addSkills(miscSkills, "sSkillClassMisc", "Misc Skills", coord1, coord2); - - WindowManager *wm = environment.mWindowManager; - ESMS::ESMStore &store = environment.mWorld->getStore(); - - if (!factions.empty()) - { - // Add a line separator if there are items above - if (!skillWidgets.empty()) - addSeparator(coord1, coord2); - - addGroup(wm->getGameSettingString("sFaction", "Faction"), coord1, coord2); - FactionList::const_iterator end = factions.end(); - for (FactionList::const_iterator it = factions.begin(); it != end; ++it) - { - const ESM::Faction *faction = store.factions.find(it->first); - addItem(faction->name, coord1, coord2); - // TODO: Faction rank should be placed in tooltip - } - } - - if (!birthSignId.empty()) - { - // Add a line separator if there are items above - if (!skillWidgets.empty()) - addSeparator(coord1, coord2); - - addGroup(wm->getGameSettingString("sSign", "Sign"), coord1, coord2); - const ESM::BirthSign *sign = store.birthSigns.find(birthSignId); - addItem(sign->name, coord1, coord2); - } - - // Add a line separator if there are items above - if (!skillWidgets.empty()) - addSeparator(coord1, coord2); - - addValueItem(wm->getGameSettingString("sReputation", "Reputation"), boost::lexical_cast(static_cast(reputation)), CS_Normal, coord1, coord2); - addValueItem(wm->getGameSettingString("sBounty", "Bounty"), boost::lexical_cast(static_cast(bounty)), CS_Normal, coord1, coord2); - - clientHeight = coord1.top; - updateScroller(); -} - -void StatsWindow::updateScroller() -{ - skillScrollerWidget->setScrollRange(std::max(clientHeight - skillClientWidget->getHeight(), 0)); - skillScrollerWidget->setScrollPage(std::max(skillClientWidget->getHeight() - lineHeight, 0)); } diff --git a/apps/openmw/mwgui/layouts.hpp b/apps/openmw/mwgui/layouts.hpp index 097790163c..ab91f4217a 100644 --- a/apps/openmw/mwgui/layouts.hpp +++ b/apps/openmw/mwgui/layouts.hpp @@ -3,9 +3,8 @@ #include -#include - #include +#include #include #include @@ -13,12 +12,10 @@ #include #include "../mwmechanics/stat.hpp" -#include "../mwworld/environment.hpp" -#include "../mwworld/world.hpp" #include "window_base.hpp" /* - This file contains classes corresponding to all the window layouts + This file contains classes corresponding to window layouts defined in resources/mygui/ *.xml. Each class inherites GUI::Layout and loads the XML file, and @@ -35,117 +32,27 @@ namespace MWGui class HUD : public OEngine::GUI::Layout { public: - HUD(int width, int height) - : Layout("openmw_hud_layout.xml") - { - setCoord(0,0, width, height); - - // Energy bars - getWidget(health, "Health"); - getWidget(magicka, "Magicka"); - getWidget(stamina, "Stamina"); - - // Item and spell images and status bars - getWidget(weapImage, "WeapImage"); - getWidget(weapStatus, "WeapStatus"); - getWidget(spellImage, "SpellImage"); - getWidget(spellStatus, "SpellStatus"); - - getWidget(effectBox, "EffectBox"); - getWidget(effect1, "Effect1"); - - getWidget(minimap, "MiniMap"); - getWidget(compass, "Compass"); - - getWidget(crosshair, "Crosshair"); - - compass->setImageTexture("textures\\compass.dds"); - crosshair->setImageTexture("textures\\target.dds"); - - // These are just demo values, you should replace these with - // real calls from outside the class later. - setWeapIcon("icons\\w\\tx_knife_iron.dds"); - setWeapStatus(90, 100); - setSpellIcon("icons\\s\\b_tx_s_rstor_health.dds"); - setSpellStatus(65, 100); - setEffect("icons\\s\\tx_s_chameleon.dds"); - } - - void setStats(int h, int hmax, int m, int mmax, int s, int smax) - { - health->setProgressRange(hmax); - health->setProgressPosition(h); - magicka->setProgressRange(mmax); - magicka->setProgressPosition(m); - stamina->setProgressRange(smax); - stamina->setProgressPosition(s); - } - - void setWeapIcon(const char *str) - { weapImage->setImageTexture(str); } - void setSpellIcon(const char *str) - { spellImage->setImageTexture(str); } - - void setWeapStatus(int s, int smax) - { - weapStatus->setProgressRange(smax); - weapStatus->setProgressPosition(s); - } - void setSpellStatus(int s, int smax) - { - spellStatus->setProgressRange(smax); - spellStatus->setProgressPosition(s); - } - - void setEffect(const char *img) - { effect1->setImageTexture(img); } - - void setValue (const std::string& id, const MWMechanics::DynamicStat& value) - { - static const char *ids[] = - { - "HBar", "MBar", "FBar", - 0 - }; - - for (int i=0; ids[i]; ++i) - if (ids[i]==id) - { - switch (i) - { - case 0: - - health->setProgressRange (value.getModified()); - health->setProgressPosition (value.getCurrent()); - break; - - case 1: - - magicka->setProgressRange (value.getModified()); - magicka->setProgressPosition (value.getCurrent()); - break; - - case 2: - - stamina->setProgressRange (value.getModified()); - stamina->setProgressPosition (value.getCurrent()); - break; - } - } - } + HUD(int width, int height, bool fpsSwitch); + void setStats(int h, int hmax, int m, int mmax, int s, int smax); + void setWeapIcon(const char *str); + void setSpellIcon(const char *str); + void setWeapStatus(int s, int smax); + void setSpellStatus(int s, int smax); + void setEffect(const char *img); + void setValue (const std::string& id, const MWMechanics::DynamicStat& value); + void setFPS(float fps); MyGUI::ProgressPtr health, magicka, stamina; - MyGUI::StaticImagePtr weapImage, spellImage; MyGUI::ProgressPtr weapStatus, spellStatus; - MyGUI::WidgetPtr effectBox; MyGUI::StaticImagePtr effect1; - MyGUI::StaticImagePtr minimap; MyGUI::StaticImagePtr compass; - MyGUI::StaticImagePtr crosshair; + + MyGUI::WidgetPtr fpsbox; + MyGUI::StaticTextPtr fpscounter; }; class MapWindow : public OEngine::GUI::Layout @@ -178,68 +85,6 @@ namespace MWGui } }; - class StatsWindow : public WindowBase - { - public: - typedef std::pair Faction; - typedef std::vector FactionList; - - typedef std::vector SkillList; - - StatsWindow (MWWorld::Environment& environment); - - void setBar(const std::string& name, const std::string& tname, int val, int max); - void setPlayerName(const std::string& playerName); - - /// Set value for the given ID. - void setValue (const std::string& id, const MWMechanics::Stat& value); - void setValue (const std::string& id, const MWMechanics::DynamicStat& value); - void setValue (const std::string& id, const std::string& value); - void setValue (const std::string& id, int value); - - void setValue (const std::string& id, const MWMechanics::Stat& value); - - void configureSkills (const SkillList& major, const SkillList& minor); - void setFactions (const std::vector& factions); - void setBirthSign (const std::string &signId); - void setReputation (int reputation) { this->reputation = reputation; } - void setBounty (int bounty) { this->bounty = bounty; } - void updateSkillArea(); - - private: - enum ColorStyle - { - CS_Sub, - CS_Normal, - CS_Super - }; - void setStyledText(MyGUI::StaticTextPtr widget, ColorStyle style, const std::string &value); - void addSkills(const SkillList &skills, const std::string &titleId, const std::string &titleDefault, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); - void addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); - void addGroup(const std::string &label, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); - MyGUI::StaticTextPtr addValueItem(const std::string text, const std::string &value, ColorStyle style, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); - void addItem(const std::string text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); - void updateScroller(); - - void onScrollChangePosition(MyGUI::VScrollPtr scroller, size_t pos); - void onWindowResize(MyGUI::WidgetPtr window); - - static const int lineHeight; - - MyGUI::WidgetPtr skillAreaWidget, skillClientWidget; - MyGUI::VScrollPtr skillScrollerWidget; - int lastPos, clientHeight; - - SkillList majorSkills, minorSkills, miscSkills; - std::map > skillValues; - std::map skillWidgetMap; - std::map factionWidgetMap; - FactionList factions; ///< Stores a list of factions and the current rank - std::string birthSignId; - int reputation, bounty; - std::vector skillWidgets; //< Skills and other information - }; - #if 0 class InventoryWindow : public OEngine::GUI::Layout { diff --git a/apps/openmw/mwgui/race.cpp b/apps/openmw/mwgui/race.cpp index 8ba9d8fe2f..65e6afd2ea 100644 --- a/apps/openmw/mwgui/race.cpp +++ b/apps/openmw/mwgui/race.cpp @@ -1,6 +1,4 @@ #include "race.hpp" -#include "../mwworld/environment.hpp" -#include "../mwworld/world.hpp" #include "window_manager.hpp" #include "widgets.hpp" #include "components/esm_store/store.hpp" @@ -15,8 +13,8 @@ using namespace MWGui; using namespace Widgets; -RaceDialog::RaceDialog(MWWorld::Environment& environment) - : WindowBase("openmw_chargen_race_layout.xml", environment) +RaceDialog::RaceDialog(WindowManager& parWindowManager) + : WindowBase("openmw_chargen_race_layout.xml", parWindowManager) , genderIndex(0) , faceIndex(0) , hairIndex(0) @@ -29,8 +27,7 @@ RaceDialog::RaceDialog(MWWorld::Environment& environment) // These are just demo values, you should replace these with // real calls from outside the class later. - WindowManager *wm = environment.mWindowManager; - setText("AppearanceT", wm->getGameSettingString("sRaceMenu1", "Appearance")); + setText("AppearanceT", mWindowManager.getGameSettingString("sRaceMenu1", "Appearance")); getWidget(appearanceBox, "AppearanceBox"); getWidget(headRotate, "HeadRotate"); @@ -42,34 +39,34 @@ RaceDialog::RaceDialog(MWWorld::Environment& environment) // Set up next/previous buttons MyGUI::ButtonPtr prevButton, nextButton; - setText("GenderChoiceT", wm->getGameSettingString("sRaceMenu2", "Change Sex")); + setText("GenderChoiceT", mWindowManager.getGameSettingString("sRaceMenu2", "Change Sex")); getWidget(prevButton, "PrevGenderButton"); getWidget(nextButton, "NextGenderButton"); prevButton->eventMouseButtonClick = MyGUI::newDelegate(this, &RaceDialog::onSelectPreviousGender); nextButton->eventMouseButtonClick = MyGUI::newDelegate(this, &RaceDialog::onSelectNextGender); - setText("FaceChoiceT", wm->getGameSettingString("sRaceMenu3", "Change Face")); + setText("FaceChoiceT", mWindowManager.getGameSettingString("sRaceMenu3", "Change Face")); getWidget(prevButton, "PrevFaceButton"); getWidget(nextButton, "NextFaceButton"); prevButton->eventMouseButtonClick = MyGUI::newDelegate(this, &RaceDialog::onSelectPreviousFace); nextButton->eventMouseButtonClick = MyGUI::newDelegate(this, &RaceDialog::onSelectNextFace); - setText("HairChoiceT", wm->getGameSettingString("sRaceMenu3", "Change Hair")); + setText("HairChoiceT", mWindowManager.getGameSettingString("sRaceMenu3", "Change Hair")); getWidget(prevButton, "PrevHairButton"); getWidget(nextButton, "NextHairButton"); prevButton->eventMouseButtonClick = MyGUI::newDelegate(this, &RaceDialog::onSelectPreviousHair); nextButton->eventMouseButtonClick = MyGUI::newDelegate(this, &RaceDialog::onSelectNextHair); - setText("RaceT", wm->getGameSettingString("sRaceMenu4", "Race")); + setText("RaceT", mWindowManager.getGameSettingString("sRaceMenu4", "Race")); getWidget(raceList, "RaceList"); raceList->setScrollVisible(true); raceList->eventListSelectAccept = MyGUI::newDelegate(this, &RaceDialog::onSelectRace); raceList->eventListMouseItemActivate = MyGUI::newDelegate(this, &RaceDialog::onSelectRace); raceList->eventListChangePosition = MyGUI::newDelegate(this, &RaceDialog::onSelectRace); - setText("SkillsT", wm->getGameSettingString("sBonusSkillTitle", "Skill Bonus")); + setText("SkillsT", mWindowManager.getGameSettingString("sBonusSkillTitle", "Skill Bonus")); getWidget(skillList, "SkillList"); - setText("SpellPowerT", wm->getGameSettingString("sRaceMenu7", "Specials")); + setText("SpellPowerT", mWindowManager.getGameSettingString("sRaceMenu7", "Specials")); getWidget(spellPowerList, "SpellPowerList"); // TODO: These buttons should be managed by a Dialog class @@ -152,7 +149,7 @@ int wrap(int index, int max) void RaceDialog::onOkClicked(MyGUI::Widget* _sender) { - eventDone(); + eventDone(this); } void RaceDialog::onBackClicked(MyGUI::Widget* _sender) @@ -215,7 +212,7 @@ void RaceDialog::updateRaces() { raceList->removeAllItems(); - ESMS::ESMStore &store = environment.mWorld->getStore(); + ESMS::ESMStore &store = mWindowManager.getStore(); ESMS::RecListT::MapType::const_iterator it = store.races.list.begin(); ESMS::RecListT::MapType::const_iterator end = store.races.list.end(); @@ -249,8 +246,7 @@ void RaceDialog::updateSkills() const int lineHeight = 18; MyGUI::IntCoord coord1(0, 0, skillList->getWidth(), 18); - WindowManager *wm = environment.mWindowManager; - ESMS::ESMStore &store = environment.mWorld->getStore(); + ESMS::ESMStore &store = mWindowManager.getStore(); const ESM::Race *race = store.races.find(currentRaceId); int count = sizeof(race->data.bonus)/sizeof(race->data.bonus[0]); // TODO: Find a portable macro for this ARRAYSIZE? for (int i = 0; i < count; ++i) @@ -261,7 +257,7 @@ void RaceDialog::updateSkills() skillWidget = skillList->createWidget("MW_StatNameValue", coord1, MyGUI::Align::Default, std::string("Skill") + boost::lexical_cast(i)); - skillWidget->setWindowManager(wm); + skillWidget->setWindowManager(&mWindowManager); skillWidget->setSkillNumber(skillId); skillWidget->setSkillValue(MWSkill::SkillValue(race->data.bonus[i].bonus)); @@ -286,7 +282,7 @@ void RaceDialog::updateSpellPowers() const int lineHeight = 18; MyGUI::IntCoord coord(0, 0, spellPowerList->getWidth(), 18); - ESMS::ESMStore &store = environment.mWorld->getStore(); + ESMS::ESMStore &store = mWindowManager.getStore(); const ESM::Race *race = store.races.find(currentRaceId); std::vector::const_iterator it = race->powers.list.begin(); @@ -295,7 +291,7 @@ void RaceDialog::updateSpellPowers() { const std::string &spellpower = *it; spellPowerWidget = spellPowerList->createWidget("MW_StatName", coord, MyGUI::Align::Default, std::string("SpellPower") + boost::lexical_cast(i)); - spellPowerWidget->setEnvironment(&environment); + spellPowerWidget->setWindowManager(&mWindowManager); spellPowerWidget->setSpellId(spellpower); spellPowerItems.push_back(spellPowerWidget); diff --git a/apps/openmw/mwgui/race.hpp b/apps/openmw/mwgui/race.hpp index 47774703cc..f2aac3a18c 100644 --- a/apps/openmw/mwgui/race.hpp +++ b/apps/openmw/mwgui/race.hpp @@ -7,9 +7,9 @@ #include -namespace MWWorld +namespace MWGui { - class Environment; + class WindowManager; } /* @@ -24,7 +24,7 @@ namespace MWGui class RaceDialog : public WindowBase { public: - RaceDialog(MWWorld::Environment& environment); + RaceDialog(WindowManager& parWindowManager); enum Gender { @@ -53,11 +53,6 @@ namespace MWGui */ EventHandle_Void eventBack; - /** Event : Dialog finished, OK button clicked.\n - signature : void method()\n - */ - EventHandle_Void eventDone; - protected: void onHeadRotate(MyGUI::VScroll* _sender, size_t _position); diff --git a/apps/openmw/mwgui/review.cpp b/apps/openmw/mwgui/review.cpp index c165d942e8..e770ec2351 100644 --- a/apps/openmw/mwgui/review.cpp +++ b/apps/openmw/mwgui/review.cpp @@ -1,6 +1,4 @@ #include "review.hpp" -#include "../mwworld/environment.hpp" -#include "../mwworld/world.hpp" #include "window_manager.hpp" #include "widgets.hpp" #include "components/esm_store/store.hpp" @@ -18,48 +16,46 @@ using namespace Widgets; const int ReviewDialog::lineHeight = 18; -ReviewDialog::ReviewDialog(MWWorld::Environment& environment) - : WindowBase("openmw_chargen_review_layout.xml", environment) +ReviewDialog::ReviewDialog(WindowManager& parWindowManager) + : WindowBase("openmw_chargen_review_layout.xml", parWindowManager) , lastPos(0) { // Centre dialog center(); - WindowManager *wm = environment.mWindowManager; - // Setup static stats ButtonPtr button; getWidget(nameWidget, "NameText"); getWidget(button, "NameButton"); - button->setCaption(wm->getGameSettingString("sName", "")); + button->setCaption(mWindowManager.getGameSettingString("sName", "")); button->eventMouseButtonClick = MyGUI::newDelegate(this, &ReviewDialog::onNameClicked);; getWidget(raceWidget, "RaceText"); getWidget(button, "RaceButton"); - button->setCaption(wm->getGameSettingString("sRace", "")); + button->setCaption(mWindowManager.getGameSettingString("sRace", "")); button->eventMouseButtonClick = MyGUI::newDelegate(this, &ReviewDialog::onRaceClicked);; getWidget(classWidget, "ClassText"); getWidget(button, "ClassButton"); - button->setCaption(wm->getGameSettingString("sClass", "")); + button->setCaption(mWindowManager.getGameSettingString("sClass", "")); button->eventMouseButtonClick = MyGUI::newDelegate(this, &ReviewDialog::onClassClicked);; getWidget(birthSignWidget, "SignText"); getWidget(button, "SignButton"); - button->setCaption(wm->getGameSettingString("sBirthSign", "")); + button->setCaption(mWindowManager.getGameSettingString("sBirthSign", "")); button->eventMouseButtonClick = MyGUI::newDelegate(this, &ReviewDialog::onBirthSignClicked);; // Setup dynamic stats getWidget(health, "Health"); - health->setTitle(wm->getGameSettingString("sHealth", "")); + health->setTitle(mWindowManager.getGameSettingString("sHealth", "")); health->setValue(45, 45); getWidget(magicka, "Magicka"); - magicka->setTitle(wm->getGameSettingString("sMagic", "")); + magicka->setTitle(mWindowManager.getGameSettingString("sMagic", "")); magicka->setValue(50, 50); getWidget(fatigue, "Fatigue"); - fatigue->setTitle(wm->getGameSettingString("sFatigue", "")); + fatigue->setTitle(mWindowManager.getGameSettingString("sFatigue", "")); fatigue->setValue(160, 160); // Setup attributes @@ -69,7 +65,7 @@ ReviewDialog::ReviewDialog(MWWorld::Environment& environment) { getWidget(attribute, std::string("Attribute") + boost::lexical_cast(idx)); attributeWidgets.insert(std::make_pair(static_cast(ESM::Attribute::attributeIds[idx]), attribute)); - attribute->setWindowManager(wm); + attribute->setWindowManager(&mWindowManager); attribute->setAttributeId(ESM::Attribute::attributeIds[idx]); attribute->setAttributeValue(MWAttribute::AttributeValue(0, 0)); } @@ -121,7 +117,7 @@ void ReviewDialog::onScrollChangePosition(MyGUI::VScrollPtr scroller, size_t pos } } -void ReviewDialog::onWindowResize(MyGUI::WidgetPtr window) +void ReviewDialog::onWindowResize(MyGUI::Window* window) { updateScroller(); } @@ -134,7 +130,7 @@ void ReviewDialog::setPlayerName(const std::string &name) void ReviewDialog::setRace(const std::string &raceId_) { raceId = raceId_; - const ESM::Race *race = environment.mWorld->getStore().races.search(raceId); + const ESM::Race *race = mWindowManager.getStore().races.search(raceId); if (race) raceWidget->setCaption(race->name); } @@ -148,7 +144,7 @@ void ReviewDialog::setClass(const ESM::Class& class_) void ReviewDialog::setBirthSign(const std::string& signId) { birthSignId = signId; - const ESM::BirthSign *sign = environment.mWorld->getStore().birthSigns.search(birthSignId); + const ESM::BirthSign *sign = mWindowManager.getStore().birthSigns.search(birthSignId); if (sign) birthSignWidget->setCaption(sign->name); } @@ -278,15 +274,13 @@ void ReviewDialog::addItem(const std::string text, MyGUI::IntCoord &coord1, MyGU void ReviewDialog::addSkills(const SkillList &skills, const std::string &titleId, const std::string &titleDefault, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) { - WindowManager *wm = environment.mWindowManager; - // Add a line separator if there are items above if (!skillWidgets.empty()) { addSeparator(coord1, coord2); } - addGroup(wm->getGameSettingString(titleId, titleDefault), coord1, coord2); + addGroup(mWindowManager.getGameSettingString(titleId, titleDefault), coord1, coord2); SkillList::const_iterator end = skills.end(); for (SkillList::const_iterator it = skills.begin(); it != end; ++it) @@ -305,7 +299,7 @@ void ReviewDialog::addSkills(const SkillList &skills, const std::string &titleId style = CS_Super; else if (modified < base) style = CS_Sub; - MyGUI::StaticTextPtr widget = addValueItem(wm->getGameSettingString(skillNameId, skillNameId), boost::lexical_cast(static_cast(modified)), style, coord1, coord2); + MyGUI::StaticTextPtr widget = addValueItem(mWindowManager.getGameSettingString(skillNameId, skillNameId), boost::lexical_cast(static_cast(modified)), style, coord1, coord2); skillWidgetMap[skillId] = widget; } } @@ -345,7 +339,7 @@ void ReviewDialog::updateScroller() void ReviewDialog::onOkClicked(MyGUI::Widget* _sender) { - eventDone(); + eventDone(this); } void ReviewDialog::onBackClicked(MyGUI::Widget* _sender) @@ -355,20 +349,20 @@ void ReviewDialog::onBackClicked(MyGUI::Widget* _sender) void ReviewDialog::onNameClicked(MyGUI::Widget* _sender) { - eventNameActivated(); + eventActivateDialog(NAME_DIALOG); } void ReviewDialog::onRaceClicked(MyGUI::Widget* _sender) { - eventRaceActivated(); + eventActivateDialog(RACE_DIALOG); } void ReviewDialog::onClassClicked(MyGUI::Widget* _sender) { - eventClassActivated(); + eventActivateDialog(CLASS_DIALOG); } void ReviewDialog::onBirthSignClicked(MyGUI::Widget* _sender) { - eventBirthSignActivated(); + eventActivateDialog(BIRTHSIGN_DIALOG); } diff --git a/apps/openmw/mwgui/review.hpp b/apps/openmw/mwgui/review.hpp index 25a183f653..5846804f7f 100644 --- a/apps/openmw/mwgui/review.hpp +++ b/apps/openmw/mwgui/review.hpp @@ -5,9 +5,9 @@ #include "../mwmechanics/stat.hpp" #include "widgets.hpp" -namespace MWWorld +namespace MWGui { - class Environment; + class WindowManager; } /* @@ -22,9 +22,15 @@ namespace MWGui class ReviewDialog : public WindowBase { public: + enum Dialogs { + NAME_DIALOG, + RACE_DIALOG, + CLASS_DIALOG, + BIRTHSIGN_DIALOG + }; typedef std::vector SkillList; - ReviewDialog(MWWorld::Environment& environment); + ReviewDialog(WindowManager& parWindowManager); void setPlayerName(const std::string &name); void setRace(const std::string &raceId); @@ -44,36 +50,14 @@ namespace MWGui // Events typedef delegates::CDelegate0 EventHandle_Void; + typedef delegates::CDelegate1 EventHandle_Int; /** Event : Back button clicked.\n signature : void method()\n */ EventHandle_Void eventBack; - /** Event : Dialog finished, OK button clicked.\n - signature : void method()\n - */ - EventHandle_Void eventDone; - - /** Event : Activate name dialog.\n - signature : void method()\n - */ - EventHandle_Void eventNameActivated; - - /** Event : Activate race dialog.\n - signature : void method()\n - */ - EventHandle_Void eventRaceActivated; - - /** Event : Activate class dialog.\n - signature : void method()\n - */ - EventHandle_Void eventClassActivated; - - /** Event : Activate birth sign dialog.\n - signature : void method()\n - */ - EventHandle_Void eventBirthSignActivated; + EventHandle_Int eventActivateDialog; protected: void onOkClicked(MyGUI::Widget* _sender); @@ -101,7 +85,7 @@ namespace MWGui void updateSkillArea(); void onScrollChangePosition(MyGUI::VScrollPtr scroller, size_t pos); - void onWindowResize(MyGUI::WidgetPtr window); + void onWindowResize(MyGUI::Window* window); static const int lineHeight; diff --git a/apps/openmw/mwgui/stats_window.cpp b/apps/openmw/mwgui/stats_window.cpp new file mode 100644 index 0000000000..d08e6384d2 --- /dev/null +++ b/apps/openmw/mwgui/stats_window.cpp @@ -0,0 +1,370 @@ +#include "stats_window.hpp" + +#include "../mwmechanics/mechanicsmanager.hpp" +#include "window_manager.hpp" + +#include +#include +#include +#include + +using namespace MWGui; +const int StatsWindow::lineHeight = 18; + +StatsWindow::StatsWindow (WindowManager& parWindowManager) + : WindowBase("openmw_stats_window_layout.xml", parWindowManager) + , lastPos(0) + , reputation(0) + , bounty(0) +{ + setCoord(0,0,498, 342); + + const char *names[][2] = + { + { "Attrib1", "sAttributeStrength" }, + { "Attrib2", "sAttributeIntelligence" }, + { "Attrib3", "sAttributeWillpower" }, + { "Attrib4", "sAttributeAgility" }, + { "Attrib5", "sAttributeSpeed" }, + { "Attrib6", "sAttributeEndurance" }, + { "Attrib7", "sAttributePersonality" }, + { "Attrib8", "sAttributeLuck" }, + { "Health_str", "sHealth" }, + { "Magicka_str", "sMagic" }, + { "Fatigue_str", "sFatigue" }, + { "Level_str", "sLevel" }, + { "Race_str", "sRace" }, + { "Class_str", "sClass" }, + { 0, 0 } + }; + + const ESMS::ESMStore &store = mWindowManager.getStore(); + for (int i=0; names[i][0]; ++i) + { + setText (names[i][0], store.gameSettings.find (names[i][1])->str); + } + + getWidget(skillAreaWidget, "Skills"); + getWidget(skillClientWidget, "SkillClient"); + getWidget(skillScrollerWidget, "SkillScroller"); + + skillScrollerWidget->eventScrollChangePosition = MyGUI::newDelegate(this, &StatsWindow::onScrollChangePosition); + updateScroller(); + + for (int i = 0; i < ESM::Skill::Length; ++i) + { + skillValues.insert(std::pair >(i, MWMechanics::Stat())); + skillWidgetMap.insert(std::pair(i, nullptr)); + } + + MyGUI::WindowPtr t = static_cast(mMainWidget); + t->eventWindowChangeCoord = MyGUI::newDelegate(this, &StatsWindow::onWindowResize); +} + +void StatsWindow::onScrollChangePosition(MyGUI::VScrollPtr scroller, size_t pos) +{ + int diff = lastPos - pos; + // Adjust position of all widget according to difference + if (diff == 0) + return; + lastPos = pos; + + std::vector::const_iterator end = skillWidgets.end(); + for (std::vector::const_iterator it = skillWidgets.begin(); it != end; ++it) + { + (*it)->setCoord((*it)->getCoord() + MyGUI::IntPoint(0, diff)); + } +} + +void StatsWindow::onWindowResize(MyGUI::Window* window) +{ + updateScroller(); +} + +void StatsWindow::setBar(const std::string& name, const std::string& tname, int val, int max) +{ + MyGUI::ProgressPtr pt; + getWidget(pt, name); + pt->setProgressRange(max); + pt->setProgressPosition(val); + + std::stringstream out; + out << val << "/" << max; + setText(tname, out.str().c_str()); +} + +void StatsWindow::setPlayerName(const std::string& playerName) +{ + mMainWidget->setCaption(playerName); +} + +void StatsWindow::setStyledText(MyGUI::StaticTextPtr widget, ColorStyle style, const std::string &value) +{ + widget->setCaption(value); + if (style == CS_Super) + widget->setTextColour(MyGUI::Colour(0, 1, 0)); + else if (style == CS_Sub) + widget->setTextColour(MyGUI::Colour(1, 0, 0)); + else + widget->setTextColour(MyGUI::Colour(1, 1, 1)); +} + +void StatsWindow::setValue (const std::string& id, const MWMechanics::Stat& value) +{ + static const char *ids[] = + { + "AttribVal1", "AttribVal2", "AttribVal3", "AttribVal4", "AttribVal5", + "AttribVal6", "AttribVal7", "AttribVal8", + 0 + }; + + for (int i=0; ids[i]; ++i) + if (ids[i]==id) + { + std::ostringstream valueString; + valueString << value.getModified(); + setText (id, valueString.str()); + + if (value.getModified()>value.getBase()) + setTextColor (id, 0, 1, 0); + else if (value.getModified()& value) +{ + static const char *ids[] = + { + "HBar", "MBar", "FBar", + 0 + }; + + for (int i=0; ids[i]; ++i) + if (ids[i]==id) + { + std::string id (ids[i]); + setBar (id, id + "T", value.getCurrent(), value.getModified()); + } +} + +void StatsWindow::setValue (const std::string& id, const std::string& value) +{ + if (id=="name") + setPlayerName (value); + else if (id=="race") + setText ("RaceText", value); + else if (id=="class") + setText ("ClassText", value); +} + +void StatsWindow::setValue (const std::string& id, int value) +{ + if (id=="level") + { + std::ostringstream text; + text << value; + setText("LevelText", text.str()); + } +} + +void StatsWindow::setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::Stat& value) +{ + skillValues[parSkill] = value; + MyGUI::StaticTextPtr widget = skillWidgetMap[(int)parSkill]; + if (widget) + { + float modified = value.getModified(), base = value.getBase(); + std::string text = boost::lexical_cast(std::floor(modified)); + ColorStyle style = CS_Normal; + if (modified > base) + style = CS_Super; + else if (modified < base) + style = CS_Sub; + + setStyledText(widget, style, text); + } +} + +void StatsWindow::configureSkills (const std::vector& major, const std::vector& minor) +{ + majorSkills = major; + minorSkills = minor; + + // Update misc skills with the remaining skills not in major or minor + std::set skillSet; + std::copy(major.begin(), major.end(), std::inserter(skillSet, skillSet.begin())); + std::copy(minor.begin(), minor.end(), std::inserter(skillSet, skillSet.begin())); + boost::array::const_iterator end = ESM::Skill::skillIds.end(); + miscSkills.clear(); + for (boost::array::const_iterator it = ESM::Skill::skillIds.begin(); it != end; ++it) + { + int skill = *it; + if (skillSet.find(skill) == skillSet.end()) + miscSkills.push_back(skill); + } +} + +void StatsWindow::setFactions (const std::vector& factions) +{ + this->factions = factions; +} + +void StatsWindow::setBirthSign (const std::string& signId) +{ + birthSignId = signId; +} + +void StatsWindow::addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) +{ + MyGUI::StaticImagePtr separator = skillClientWidget->createWidget("MW_HLine", MyGUI::IntCoord(10, coord1.top, coord1.width + coord2.width - 4, 18), MyGUI::Align::Default); + skillWidgets.push_back(separator); + + coord1.top += separator->getHeight(); + coord2.top += separator->getHeight(); +} + +void StatsWindow::addGroup(const std::string &label, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) +{ + MyGUI::StaticTextPtr groupWidget = skillClientWidget->createWidget("SandBrightText", MyGUI::IntCoord(0, coord1.top, coord1.width + coord2.width, coord1.height), MyGUI::Align::Default); + groupWidget->setCaption(label); + skillWidgets.push_back(groupWidget); + + coord1.top += lineHeight; + coord2.top += lineHeight; +} + +MyGUI::StaticTextPtr StatsWindow::addValueItem(const std::string text, const std::string &value, ColorStyle style, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) +{ + MyGUI::StaticTextPtr skillNameWidget, skillValueWidget; + + skillNameWidget = skillClientWidget->createWidget("SandText", coord1, MyGUI::Align::Default); + skillNameWidget->setCaption(text); + + skillValueWidget = skillClientWidget->createWidget("SandTextRight", coord2, MyGUI::Align::Default); + setStyledText(skillValueWidget, style, value); + + skillWidgets.push_back(skillNameWidget); + skillWidgets.push_back(skillValueWidget); + + coord1.top += lineHeight; + coord2.top += lineHeight; + + return skillValueWidget; +} + +void StatsWindow::addItem(const std::string text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) +{ + MyGUI::StaticTextPtr skillNameWidget; + + skillNameWidget = skillClientWidget->createWidget("SandText", coord1 + MyGUI::IntSize(coord2.width, 0), MyGUI::Align::Default); + skillNameWidget->setCaption(text); + + skillWidgets.push_back(skillNameWidget); + + coord1.top += lineHeight; + coord2.top += lineHeight; +} + +void StatsWindow::addSkills(const SkillList &skills, const std::string &titleId, const std::string &titleDefault, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) +{ + // Add a line separator if there are items above + if (!skillWidgets.empty()) + { + addSeparator(coord1, coord2); + } + + addGroup(mWindowManager.getGameSettingString(titleId, titleDefault), coord1, coord2); + + SkillList::const_iterator end = skills.end(); + for (SkillList::const_iterator it = skills.begin(); it != end; ++it) + { + int skillId = *it; + if (skillId < 0 || skillId > ESM::Skill::Length) // Skip unknown skill indexes + continue; + assert(skillId >= 0 && skillId < ESM::Skill::Length); + const std::string &skillNameId = ESMS::Skill::sSkillNameIds[skillId]; + const MWMechanics::Stat &stat = skillValues.find(skillId)->second; + float base = stat.getBase(); + float modified = stat.getModified(); + + ColorStyle style = CS_Normal; + if (modified > base) + style = CS_Super; + else if (modified < base) + style = CS_Sub; + MyGUI::StaticTextPtr widget = addValueItem(mWindowManager.getGameSettingString(skillNameId, skillNameId), boost::lexical_cast(static_cast(modified)), style, coord1, coord2); + skillWidgetMap[skillId] = widget; + } +} + +void StatsWindow::updateSkillArea() +{ + for (std::vector::iterator it = skillWidgets.begin(); it != skillWidgets.end(); ++it) + { + MyGUI::Gui::getInstance().destroyWidget(*it); + } + skillWidgets.clear(); + + const int valueSize = 40; + MyGUI::IntCoord coord1(10, 0, skillClientWidget->getWidth() - (10 + valueSize), 18); + MyGUI::IntCoord coord2(coord1.left + coord1.width, coord1.top, valueSize, coord1.height); + + if (!majorSkills.empty()) + addSkills(majorSkills, "sSkillClassMajor", "Major Skills", coord1, coord2); + + if (!minorSkills.empty()) + addSkills(minorSkills, "sSkillClassMinor", "Minor Skills", coord1, coord2); + + if (!miscSkills.empty()) + addSkills(miscSkills, "sSkillClassMisc", "Misc Skills", coord1, coord2); + + ESMS::ESMStore &store = mWindowManager.getStore(); + + if (!factions.empty()) + { + // Add a line separator if there are items above + if (!skillWidgets.empty()) + addSeparator(coord1, coord2); + + addGroup(mWindowManager.getGameSettingString("sFaction", "Faction"), coord1, coord2); + FactionList::const_iterator end = factions.end(); + for (FactionList::const_iterator it = factions.begin(); it != end; ++it) + { + const ESM::Faction *faction = store.factions.find(it->first); + addItem(faction->name, coord1, coord2); + // TODO: Faction rank should be placed in tooltip + } + } + + if (!birthSignId.empty()) + { + // Add a line separator if there are items above + if (!skillWidgets.empty()) + addSeparator(coord1, coord2); + + addGroup(mWindowManager.getGameSettingString("sSign", "Sign"), coord1, coord2); + const ESM::BirthSign *sign = store.birthSigns.find(birthSignId); + addItem(sign->name, coord1, coord2); + } + + // Add a line separator if there are items above + if (!skillWidgets.empty()) + addSeparator(coord1, coord2); + + addValueItem(mWindowManager.getGameSettingString("sReputation", "Reputation"), boost::lexical_cast(static_cast(reputation)), CS_Normal, coord1, coord2); + addValueItem(mWindowManager.getGameSettingString("sBounty", "Bounty"), boost::lexical_cast(static_cast(bounty)), CS_Normal, coord1, coord2); + + clientHeight = coord1.top; + updateScroller(); +} + +void StatsWindow::updateScroller() +{ + skillScrollerWidget->setScrollRange(std::max(clientHeight - skillClientWidget->getHeight(), 0)); + skillScrollerWidget->setScrollPage(std::max(skillClientWidget->getHeight() - lineHeight, 0)); +} diff --git a/apps/openmw/mwgui/stats_window.hpp b/apps/openmw/mwgui/stats_window.hpp new file mode 100644 index 0000000000..9db5c240b1 --- /dev/null +++ b/apps/openmw/mwgui/stats_window.hpp @@ -0,0 +1,80 @@ +#ifndef MWGUI_STATS_WINDOW_H +#define MWGUI_STATS_WINDOW_H + +#include + +#include +#include +#include +#include + +#include "../mwmechanics/stat.hpp" +#include "window_base.hpp" + +namespace MWGui +{ + class WindowManager; + + class StatsWindow : public WindowBase + { + public: + typedef std::pair Faction; + typedef std::vector FactionList; + + typedef std::vector SkillList; + + StatsWindow(WindowManager& parWindowManager); + + void setBar(const std::string& name, const std::string& tname, int val, int max); + void setPlayerName(const std::string& playerName); + + /// Set value for the given ID. + void setValue (const std::string& id, const MWMechanics::Stat& value); + void setValue (const std::string& id, const MWMechanics::DynamicStat& value); + void setValue (const std::string& id, const std::string& value); + void setValue (const std::string& id, int value); + void setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::Stat& value); + + void configureSkills (const SkillList& major, const SkillList& minor); + void setFactions (const std::vector& factions); + void setBirthSign (const std::string &signId); + void setReputation (int reputation) { this->reputation = reputation; } + void setBounty (int bounty) { this->bounty = bounty; } + void updateSkillArea(); + + private: + enum ColorStyle + { + CS_Sub, + CS_Normal, + CS_Super + }; + void setStyledText(MyGUI::StaticTextPtr widget, ColorStyle style, const std::string &value); + void addSkills(const SkillList &skills, const std::string &titleId, const std::string &titleDefault, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); + void addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); + void addGroup(const std::string &label, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); + MyGUI::StaticTextPtr addValueItem(const std::string text, const std::string &value, ColorStyle style, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); + void addItem(const std::string text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); + void updateScroller(); + + void onScrollChangePosition(MyGUI::VScrollPtr scroller, size_t pos); + void onWindowResize(MyGUI::Window* window); + + static const int lineHeight; + + MyGUI::WidgetPtr skillAreaWidget, skillClientWidget; + MyGUI::VScrollPtr skillScrollerWidget; + int lastPos, clientHeight; + + SkillList majorSkills, minorSkills, miscSkills; + std::map > skillValues; + std::map skillWidgetMap; + std::map factionWidgetMap; + FactionList factions; ///< Stores a list of factions and the current rank + std::string birthSignId; + int reputation, bounty; + std::vector skillWidgets; //< Skills and other information + }; +} +#endif + diff --git a/apps/openmw/mwgui/text_input.cpp b/apps/openmw/mwgui/text_input.cpp index 3758e75e6c..83ebef6576 100644 --- a/apps/openmw/mwgui/text_input.cpp +++ b/apps/openmw/mwgui/text_input.cpp @@ -1,12 +1,10 @@ #include "text_input.hpp" #include "window_manager.hpp" -#include "../mwworld/environment.hpp" -#include "../mwworld/world.hpp" using namespace MWGui; -TextInputDialog::TextInputDialog(MWWorld::Environment& environment) - : WindowBase("openmw_text_input_layout.xml", environment) +TextInputDialog::TextInputDialog(WindowManager& parWindowManager) + : WindowBase("openmw_text_input_layout.xml", parWindowManager) { // Centre dialog center(); @@ -55,10 +53,10 @@ void TextInputDialog::open() void TextInputDialog::onOkClicked(MyGUI::Widget* _sender) { - eventDone(); + eventDone(this); } void TextInputDialog::onTextAccepted(MyGUI::Edit* _sender) { - eventDone(); + eventDone(this); } diff --git a/apps/openmw/mwgui/text_input.hpp b/apps/openmw/mwgui/text_input.hpp index 9ca55715b9..fe355655f4 100644 --- a/apps/openmw/mwgui/text_input.hpp +++ b/apps/openmw/mwgui/text_input.hpp @@ -3,9 +3,9 @@ #include "window_base.hpp" -namespace MWWorld +namespace MWGui { - class Environment; + class WindowManager; } /* @@ -18,7 +18,7 @@ namespace MWGui class TextInputDialog : public WindowBase { public: - TextInputDialog(MWWorld::Environment& environment); + TextInputDialog(WindowManager& parWindowManager); std::string getTextInput() const { return textEdit ? textEdit->getOnlyText() : ""; } void setTextInput(const std::string &text) { if (textEdit) textEdit->setOnlyText(text); } @@ -27,14 +27,6 @@ namespace MWGui void setTextLabel(const std::string &label); void open(); - // Events - typedef delegates::CDelegate0 EventHandle_Void; - - /** Event : Dialog finished, OK button clicked.\n - signature : void method()\n - */ - EventHandle_Void eventDone; - protected: void onOkClicked(MyGUI::Widget* _sender); void onTextAccepted(MyGUI::Edit* _sender); diff --git a/apps/openmw/mwgui/widgets.cpp b/apps/openmw/mwgui/widgets.cpp index a665097582..861939b7ed 100644 --- a/apps/openmw/mwgui/widgets.cpp +++ b/apps/openmw/mwgui/widgets.cpp @@ -1,7 +1,5 @@ #include "widgets.hpp" #include "window_manager.hpp" -#include "../mwworld/environment.hpp" -#include "../mwworld/world.hpp" #include "components/esm_store/store.hpp" #include @@ -267,7 +265,7 @@ void MWAttribute::shutdownWidgetSkin() /* MWSpell */ MWSpell::MWSpell() - : env(nullptr) + : mWindowManager(nullptr) , spellNameWidget(nullptr) { } @@ -280,7 +278,7 @@ void MWSpell::setSpellId(const std::string &spellId) void MWSpell::createEffectWidgets(std::vector &effects, MyGUI::WidgetPtr creator, MyGUI::IntCoord &coord) { - ESMS::ESMStore &store = env->mWorld->getStore(); + ESMS::ESMStore &store = mWindowManager->getStore(); const ESM::Spell *spell = store.spells.search(id); MYGUI_ASSERT(spell, "spell with id '" << id << "' not found"); @@ -289,7 +287,7 @@ void MWSpell::createEffectWidgets(std::vector &effects, MyGUI: for (std::vector::const_iterator it = spell->effects.list.begin(); it != end; ++it) { effect = creator->createWidget("MW_EffectImage", coord, MyGUI::Align::Default); - effect->setEnvironment(env); + effect->setWindowManager(mWindowManager); effect->setSpellEffect(*it); effects.push_back(effect); coord.top += effect->getHeight(); @@ -298,9 +296,9 @@ void MWSpell::createEffectWidgets(std::vector &effects, MyGUI: void MWSpell::updateWidgets() { - if (spellNameWidget && env) + if (spellNameWidget && mWindowManager) { - ESMS::ESMStore &store = env->mWorld->getStore(); + ESMS::ESMStore &store = mWindowManager->getStore(); const ESM::Spell *spell = store.spells.search(id); if (spell) spellNameWidget->setCaption(spell->name); @@ -348,7 +346,7 @@ void MWSpell::shutdownWidgetSkin() /* MWSpellEffect */ MWSpellEffect::MWSpellEffect() - : env(nullptr) + : mWindowManager(nullptr) , imageWidget(nullptr) , textWidget(nullptr) { @@ -362,11 +360,10 @@ void MWSpellEffect::setSpellEffect(SpellEffectValue value) void MWSpellEffect::updateWidgets() { - if (!env) + if (!mWindowManager) return; - ESMS::ESMStore &store = env->mWorld->getStore(); - WindowManager *wm = env->mWindowManager; + ESMS::ESMStore &store = mWindowManager->getStore(); const ESM::MagicEffect *magicEffect = store.magicEffects.search(effect.effectID); if (textWidget) { @@ -376,7 +373,7 @@ void MWSpellEffect::updateWidgets() std::string spellLine = ""; if (effect.skill >= 0 && effect.skill < ESM::Skill::Length) { - spellLine += " " + wm->getGameSettingString(ESM::Skill::sSkillNameIds[effect.skill], ""); + spellLine += " " + mWindowManager->getGameSettingString(ESM::Skill::sSkillNameIds[effect.skill], ""); } if (effect.attribute >= 0 && effect.attribute < 8) { @@ -390,7 +387,7 @@ void MWSpellEffect::updateWidgets() "sAttributePersonality", "sAttributeLuck" }; - spellLine += " " + wm->getGameSettingString(attributes[effect.attribute], ""); + spellLine += " " + mWindowManager->getGameSettingString(attributes[effect.attribute], ""); } if (effect.magnMin >= 0 || effect.magnMax >= 0) { diff --git a/apps/openmw/mwgui/widgets.hpp b/apps/openmw/mwgui/widgets.hpp index 57cba6a0a5..cba8fefd32 100644 --- a/apps/openmw/mwgui/widgets.hpp +++ b/apps/openmw/mwgui/widgets.hpp @@ -7,11 +7,6 @@ #include "../mwmechanics/stat.hpp" -namespace MWWorld -{ - class Environment; -} - /* This file contains various custom widgets used in OpenMW. */ @@ -129,11 +124,10 @@ namespace MWGui typedef MWMechanics::Stat SpellValue; - void setEnvironment(MWWorld::Environment *env_) { env = env_; } + void setWindowManager(WindowManager* parWindowManager) { mWindowManager = parWindowManager; } void setSpellId(const std::string &id); void createEffectWidgets(std::vector &effects, MyGUI::WidgetPtr creator, MyGUI::IntCoord &coord); - MWWorld::Environment *getEnvironment() const { return env; } const std::string &getSpellId() const { return id; } /*internal:*/ @@ -150,7 +144,7 @@ namespace MWGui void updateWidgets(); - MWWorld::Environment *env; + WindowManager* mWindowManager; std::string id; MyGUI::StaticTextPtr spellNameWidget; }; @@ -164,10 +158,9 @@ namespace MWGui typedef ESM::ENAMstruct SpellEffectValue; - void setEnvironment(MWWorld::Environment *env_) { env = env_; } + void setWindowManager(WindowManager* parWindowManager) { mWindowManager = parWindowManager; } void setSpellEffect(SpellEffectValue value); - MWWorld::Environment *getEnvironment() const { return env; } const SpellEffectValue &getSpellEffect() const { return effect; } /*internal:*/ @@ -184,7 +177,7 @@ namespace MWGui void updateWidgets(); - MWWorld::Environment *env; + WindowManager* mWindowManager; SpellEffectValue effect; MyGUI::StaticImagePtr imageWidget; MyGUI::StaticTextPtr textWidget; diff --git a/apps/openmw/mwgui/window_base.cpp b/apps/openmw/mwgui/window_base.cpp index d6c0a8bfca..192dcd988d 100644 --- a/apps/openmw/mwgui/window_base.cpp +++ b/apps/openmw/mwgui/window_base.cpp @@ -1,12 +1,11 @@ #include "window_base.hpp" -#include "../mwworld/environment.hpp" #include "window_manager.hpp" using namespace MWGui; -WindowBase::WindowBase(const std::string& parLayout, MWWorld::Environment& parEnvironment) +WindowBase::WindowBase(const std::string& parLayout, WindowManager& parWindowManager) : Layout(parLayout) - , environment(parEnvironment) + , mWindowManager(parWindowManager) { } @@ -17,7 +16,7 @@ void WindowBase::open() void WindowBase::center() { // Centre dialog - MyGUI::IntSize gameWindowSize = environment.mWindowManager->getGui()->getViewSize(); + MyGUI::IntSize gameWindowSize = mWindowManager.getGui()->getViewSize(); MyGUI::IntCoord coord = mMainWidget->getCoord(); coord.left = (gameWindowSize.width - coord.width)/2; coord.top = (gameWindowSize.height - coord.height)/2; diff --git a/apps/openmw/mwgui/window_base.hpp b/apps/openmw/mwgui/window_base.hpp index 931e7ece1e..84fb601e32 100644 --- a/apps/openmw/mwgui/window_base.hpp +++ b/apps/openmw/mwgui/window_base.hpp @@ -3,23 +3,28 @@ #include -namespace MWWorld -{ - class Environment; -} - namespace MWGui { + class WindowManager; + class WindowBase: public OEngine::GUI::Layout { public: - WindowBase(const std::string& parLayout, MWWorld::Environment& parEnvironment); + WindowBase(const std::string& parLayout, WindowManager& parWindowManager); + + // Events + typedef MyGUI::delegates::CDelegate1 EventHandle_WindowBase; virtual void open(); void center(); + /** Event : Dialog finished, OK button clicked.\n + signature : void method()\n + */ + EventHandle_WindowBase eventDone; + protected: - MWWorld::Environment& environment; + WindowManager& mWindowManager; }; } diff --git a/apps/openmw/mwgui/window_manager.cpp b/apps/openmw/mwgui/window_manager.cpp index bbc266cb5b..f0c409cbe3 100644 --- a/apps/openmw/mwgui/window_manager.cpp +++ b/apps/openmw/mwgui/window_manager.cpp @@ -7,6 +7,7 @@ #include "review.hpp" #include "dialogue.hpp" #include "dialogue_history.hpp" +#include "stats_window.hpp" #include "../mwmechanics/mechanicsmanager.hpp" #include "../mwinput/inputmanager.hpp" @@ -20,7 +21,7 @@ using namespace MWGui; WindowManager::WindowManager(MyGUI::Gui *_gui, MWWorld::Environment& environment, - const Compiler::Extensions& extensions, bool newGame) + const Compiler::Extensions& extensions, bool fpsSwitch, bool newGame) : environment(environment) , nameDialog(nullptr) , raceDialog(nullptr) @@ -32,11 +33,6 @@ WindowManager::WindowManager(MyGUI::Gui *_gui, MWWorld::Environment& environment , createClassDialog(nullptr) , birthSignDialog(nullptr) , reviewDialog(nullptr) - , nameChosen(false) - , raceChosen(false) - , classChosen(false) - , birthSignChosen(false) - , reviewNext(false) , gui(_gui) , mode(GM_Game) , nextMode(GM_Game) @@ -44,65 +40,68 @@ WindowManager::WindowManager(MyGUI::Gui *_gui, MWWorld::Environment& environment , shown(GW_ALL) , allowed(newGame ? GW_None : GW_ALL) { + showFPSCounter = fpsSwitch; + + creationStage = NotStarted; //Register own widgets with MyGUI MyGUI::FactoryManager::getInstance().registerFactory("Widget"); - // Get size info from the Gui object - assert(gui); - int w = gui->getViewSize().width; - int h = gui->getViewSize().height; + // Get size info from the Gui object + assert(gui); + int w = gui->getViewSize().width; + int h = gui->getViewSize().height; - hud = new HUD(w,h); - menu = new MainMenu(w,h); - map = new MapWindow(); - stats = new StatsWindow (environment); + hud = new HUD(w,h, showFPSCounter); + menu = new MainMenu(w,h); + map = new MapWindow(); + stats = new StatsWindow(*this); #if 0 - inventory = new InventoryWindow (); + inventory = new InventoryWindow (); #endif - console = new Console(w,h, environment, extensions); + console = new Console(w,h, environment, extensions); - // The HUD is always on - hud->setVisible(true); + // The HUD is always on + hud->setVisible(true); - // Setup player stats - for (int i = 0; i < ESM::Attribute::Length; ++i) - { - playerAttributes.insert(std::make_pair(ESM::Attribute::attributeIds[i], MWMechanics::Stat())); - } + // Setup player stats + for (int i = 0; i < ESM::Attribute::Length; ++i) + { + playerAttributes.insert(std::make_pair(ESM::Attribute::attributeIds[i], MWMechanics::Stat())); + } - for (int i = 0; i < ESM::Skill::Length; ++i) - { - playerSkillValues.insert(std::make_pair(ESM::Skill::skillIds[i], MWMechanics::Stat())); - } + for (int i = 0; i < ESM::Skill::Length; ++i) + { + playerSkillValues.insert(std::make_pair(ESM::Skill::skillIds[i], MWMechanics::Stat())); + } - // Set up visibility - updateVisible(); + // Set up visibility + updateVisible(); } WindowManager::~WindowManager() { - delete console; - delete hud; - delete map; - delete menu; - delete stats; + delete console; + delete hud; + delete map; + delete menu; + delete stats; #if 0 - delete inventory; + delete inventory; #endif - delete nameDialog; - delete raceDialog; - delete dialogueWindow; - delete classChoiceDialog; - delete generateClassQuestionDialog; - delete generateClassResultDialog; - delete pickClassDialog; - delete createClassDialog; - delete birthSignDialog; - delete reviewDialog; + delete nameDialog; + delete raceDialog; + delete dialogueWindow; + delete classChoiceDialog; + delete generateClassQuestionDialog; + delete generateClassResultDialog; + delete pickClassDialog; + delete createClassDialog; + delete birthSignDialog; + delete reviewDialog; - cleanupGarbage(); + cleanupGarbage(); } void WindowManager::cleanupGarbage() @@ -127,6 +126,10 @@ void WindowManager::update() environment.mInputManager->setGuiMode(nextMode); nextMode = GM_Game; } + if (showFPSCounter) + { + hud->setFPS(mFPS); + } } void WindowManager::setNextMode(GuiMode newMode) @@ -142,198 +145,193 @@ void WindowManager::setGuiMode(GuiMode newMode) void WindowManager::updateVisible() { - // Start out by hiding everything except the HUD - map->setVisible(false); - menu->setVisible(false); - stats->setVisible(false); + // Start out by hiding everything except the HUD + map->setVisible(false); + menu->setVisible(false); + stats->setVisible(false); #if 0 - inventory->setVisible(false); + inventory->setVisible(false); #endif - console->disable(); - - // Mouse is visible whenever we're not in game mode - gui->setVisiblePointer(isGuiMode()); - - // If in game mode, don't show anything. - if(mode == GM_Game) - { - return; - } - - if(mode == GM_MainMenu) - { - // Enable the main menu - menu->setVisible(true); - return; - } - - if(mode == GM_Console) - { - console->enable(); - return; - } - - if (mode == GM_Name) - { - if (nameDialog) - removeDialog(nameDialog); - nameDialog = new TextInputDialog(environment); - std::string sName = getGameSettingString("sName", "Name"); - nameDialog->setTextLabel(sName); - nameDialog->setTextInput(playerName); - nameDialog->setNextButtonShow(nameChosen || reviewNext); - nameDialog->eventDone = MyGUI::newDelegate(this, &WindowManager::onNameDialogDone); - nameDialog->open(); - return; - } - - if (mode == GM_Race) - { - if (raceDialog) - removeDialog(raceDialog); - raceDialog = new RaceDialog(environment); - raceDialog->setNextButtonShow(raceChosen || reviewNext); - raceDialog->setRaceId(playerRaceId); - raceDialog->eventDone = MyGUI::newDelegate(this, &WindowManager::onRaceDialogDone); - raceDialog->eventBack = MyGUI::newDelegate(this, &WindowManager::onRaceDialogBack); - raceDialog->open(); - return; - } - - if (mode == GM_Class) - { - if (classChoiceDialog) - removeDialog(classChoiceDialog); - classChoiceDialog = new ClassChoiceDialog(environment); - classChoiceDialog->eventButtonSelected = MyGUI::newDelegate(this, &WindowManager::onClassChoice); - classChoiceDialog->open(); - return; - } - - if (mode == GM_ClassGenerate) - { - generateClassStep = 0; - generateClass = ""; - generateClassSpecializations[0] = 0; - generateClassSpecializations[1] = 0; - generateClassSpecializations[2] = 0; - showClassQuestionDialog(); - return; - } - - if (mode == GM_ClassPick) - { - if (pickClassDialog) - removeDialog(pickClassDialog); - pickClassDialog = new PickClassDialog(environment); - pickClassDialog->setNextButtonShow(classChosen || reviewNext); - pickClassDialog->setClassId(playerClass.name); - pickClassDialog->eventDone = MyGUI::newDelegate(this, &WindowManager::onPickClassDialogDone); - pickClassDialog->eventBack = MyGUI::newDelegate(this, &WindowManager::onPickClassDialogBack); - pickClassDialog->open(); - return; - } - - if (mode == GM_ClassCreate) - { - if (createClassDialog) - removeDialog(createClassDialog); - createClassDialog = new CreateClassDialog(environment); - createClassDialog->eventDone = MyGUI::newDelegate(this, &WindowManager::onCreateClassDialogDone); - createClassDialog->eventBack = MyGUI::newDelegate(this, &WindowManager::onCreateClassDialogBack); - createClassDialog->open(); - return; - } - - if (mode == GM_Birth) - { - if (birthSignDialog) - removeDialog(birthSignDialog); - birthSignDialog = new BirthDialog(environment); - birthSignDialog->setNextButtonShow(birthSignChosen || reviewNext); - birthSignDialog->setBirthId(playerBirthSignId); - birthSignDialog->eventDone = MyGUI::newDelegate(this, &WindowManager::onBirthSignDialogDone); - birthSignDialog->eventBack = MyGUI::newDelegate(this, &WindowManager::onBirthSignDialogBack); - birthSignDialog->open(); - return; - } - - if (mode == GM_Review) - { - reviewNext = false; - if (reviewDialog) - removeDialog(reviewDialog); - reviewDialog = new ReviewDialog(environment); - reviewDialog->setPlayerName(playerName); - reviewDialog->setRace(playerRaceId); - reviewDialog->setClass(playerClass); - reviewDialog->setBirthSign(playerBirthSignId); - - reviewDialog->setHealth(playerHealth); - reviewDialog->setMagicka(playerMagicka); - reviewDialog->setFatigue(playerFatigue); - - { - std::map >::iterator end = playerAttributes.end(); - for (std::map >::iterator it = playerAttributes.begin(); it != end; ++it) - { - reviewDialog->setAttribute(it->first, it->second); - } - } - - { - std::map >::iterator end = playerSkillValues.end(); - for (std::map >::iterator it = playerSkillValues.begin(); it != end; ++it) - { - reviewDialog->setSkillValue(it->first, it->second); - } - reviewDialog->configureSkills(playerMajorSkills, playerMinorSkills); - } - - reviewDialog->eventDone = MyGUI::newDelegate(this, &WindowManager::onReviewDialogDone); - reviewDialog->eventBack = MyGUI::newDelegate(this, &WindowManager::onReviewDialogBack); - - reviewDialog->eventNameActivated = MyGUI::newDelegate(this, &WindowManager::onNameDialogActivate); - reviewDialog->eventRaceActivated = MyGUI::newDelegate(this, &WindowManager::onRaceDialogActivate); - reviewDialog->eventClassActivated = MyGUI::newDelegate(this, &WindowManager::onClassDialogActivate); - reviewDialog->eventBirthSignActivated = MyGUI::newDelegate(this, &WindowManager::onBirthSignDialogActivate); - - reviewDialog->open(); - return; - } - - if(mode == GM_Inventory) - { - // Ah, inventory mode. First, compute the effective set of - // windows to show. This is controlled both by what windows the - // user has opened/closed (the 'shown' variable) and by what - // windows we are allowed to show (the 'allowed' var.) - int eff = shown & allowed; - - // Show the windows we want - map -> setVisible( (eff & GW_Map) != 0 ); - stats -> setVisible( (eff & GW_Stats) != 0 ); + console->disable(); + + // Mouse is visible whenever we're not in game mode + gui->setVisiblePointer(isGuiMode()); + + // If in game mode, don't show anything. + if(mode == GM_Game) + { + return; + } + + if(mode == GM_MainMenu) + { + // Enable the main menu + menu->setVisible(true); + return; + } + + if(mode == GM_Console) + { + console->enable(); + return; + } + + if (mode == GM_Name) + { + if (nameDialog) + removeDialog(nameDialog); + nameDialog = new TextInputDialog(*this); + std::string sName = getGameSettingString("sName", "Name"); + nameDialog->setTextLabel(sName); + nameDialog->setTextInput(playerName); + nameDialog->setNextButtonShow(creationStage >= NameChosen); + nameDialog->eventDone = MyGUI::newDelegate(this, &WindowManager::onNameDialogDone); + nameDialog->open(); + return; + } + + if (mode == GM_Race) + { + if (raceDialog) + removeDialog(raceDialog); + raceDialog = new RaceDialog(*this); + raceDialog->setNextButtonShow(creationStage >= RaceChosen); + raceDialog->setRaceId(playerRaceId); + raceDialog->eventDone = MyGUI::newDelegate(this, &WindowManager::onRaceDialogDone); + raceDialog->eventBack = MyGUI::newDelegate(this, &WindowManager::onRaceDialogBack); + raceDialog->open(); + return; + } + + if (mode == GM_Class) + { + if (classChoiceDialog) + removeDialog(classChoiceDialog); + classChoiceDialog = new ClassChoiceDialog(*this); + classChoiceDialog->eventButtonSelected = MyGUI::newDelegate(this, &WindowManager::onClassChoice); + classChoiceDialog->open(); + return; + } + + if (mode == GM_ClassGenerate) + { + generateClassStep = 0; + generateClass = ""; + generateClassSpecializations[0] = 0; + generateClassSpecializations[1] = 0; + generateClassSpecializations[2] = 0; + showClassQuestionDialog(); + return; + } + + if (mode == GM_ClassPick) + { + if (pickClassDialog) + removeDialog(pickClassDialog); + pickClassDialog = new PickClassDialog(*this); + pickClassDialog->setNextButtonShow(creationStage >= ClassChosen); + pickClassDialog->setClassId(playerClass.name); + pickClassDialog->eventDone = MyGUI::newDelegate(this, &WindowManager::onPickClassDialogDone); + pickClassDialog->eventBack = MyGUI::newDelegate(this, &WindowManager::onPickClassDialogBack); + pickClassDialog->open(); + return; + } + + if (mode == GM_ClassCreate) + { + if (createClassDialog) + removeDialog(createClassDialog); + createClassDialog = new CreateClassDialog(*this); + createClassDialog->eventDone = MyGUI::newDelegate(this, &WindowManager::onCreateClassDialogDone); + createClassDialog->eventBack = MyGUI::newDelegate(this, &WindowManager::onCreateClassDialogBack); + createClassDialog->open(); + return; + } + + if (mode == GM_Birth) + { + if (birthSignDialog) + removeDialog(birthSignDialog); + birthSignDialog = new BirthDialog(*this); + birthSignDialog->setNextButtonShow(creationStage >= BirthSignChosen); + birthSignDialog->setBirthId(playerBirthSignId); + birthSignDialog->eventDone = MyGUI::newDelegate(this, &WindowManager::onBirthSignDialogDone); + birthSignDialog->eventBack = MyGUI::newDelegate(this, &WindowManager::onBirthSignDialogBack); + birthSignDialog->open(); + return; + } + + if (mode == GM_Review) + { + if (reviewDialog) + removeDialog(reviewDialog); + reviewDialog = new ReviewDialog(*this); + reviewDialog->setPlayerName(playerName); + reviewDialog->setRace(playerRaceId); + reviewDialog->setClass(playerClass); + reviewDialog->setBirthSign(playerBirthSignId); + + reviewDialog->setHealth(playerHealth); + reviewDialog->setMagicka(playerMagicka); + reviewDialog->setFatigue(playerFatigue); + + { + std::map >::iterator end = playerAttributes.end(); + for (std::map >::iterator it = playerAttributes.begin(); it != end; ++it) + { + reviewDialog->setAttribute(it->first, it->second); + } + } + + { + std::map >::iterator end = playerSkillValues.end(); + for (std::map >::iterator it = playerSkillValues.begin(); it != end; ++it) + { + reviewDialog->setSkillValue(it->first, it->second); + } + reviewDialog->configureSkills(playerMajorSkills, playerMinorSkills); + } + + reviewDialog->eventDone = MyGUI::newDelegate(this, &WindowManager::onReviewDialogDone); + reviewDialog->eventBack = MyGUI::newDelegate(this, &WindowManager::onReviewDialogBack); + reviewDialog->eventActivateDialog = MyGUI::newDelegate(this, &WindowManager::onReviewActivateDialog); + reviewDialog->open(); + return; + } + + if(mode == GM_Inventory) + { + // Ah, inventory mode. First, compute the effective set of + // windows to show. This is controlled both by what windows the + // user has opened/closed (the 'shown' variable) and by what + // windows we are allowed to show (the 'allowed' var.) + int eff = shown & allowed; + + // Show the windows we want + map -> setVisible( (eff & GW_Map) != 0 ); + stats -> setVisible( (eff & GW_Stats) != 0 ); #if 0 -// inventory -> setVisible( eff & GW_Inventory ); + // inventory -> setVisible( eff & GW_Inventory ); #endif - return; + return; } - if (mode == GM_Dialogue) - { - if (dialogueWindow) - removeDialog(dialogueWindow); - dialogueWindow = new DialogueWindow(environment); - dialogueWindow->eventBye = MyGUI::newDelegate(this, &WindowManager::onDialogueWindowBye); - dialogueWindow->open(); - return; - } + if (mode == GM_Dialogue) + { + if (!dialogueWindow) + { + dialogueWindow = new DialogueWindow(*this); + dialogueWindow->eventBye = MyGUI::newDelegate(this, &WindowManager::onDialogueWindowBye); + } + dialogueWindow->open(); + return; + } - // Unsupported mode, switch back to game - // Note: The call will eventually end up this method again but - // will stop at the check if(mode == GM_Game) above. - setGuiMode(GM_Game); + // Unsupported mode, switch back to game + // Note: The call will eventually end up this method again but + // will stop at the check if(mode == GM_Game) above. + setGuiMode(GM_Game); } void WindowManager::setValue (const std::string& id, const MWMechanics::Stat& value) @@ -365,49 +363,11 @@ void WindowManager::setValue (const std::string& id, const MWMechanics::Stat& value) -{ - stats->setValue (id, value); - static struct {const char *id; ESM::Skill::SkillEnum skillId; } skillMap[] = - { - {"SkillBlock", ESM::Skill::Block}, - {"SkillArmorer", ESM::Skill::Armorer}, - {"SkillMediumArmor", ESM::Skill::MediumArmor}, - {"SkillHeavyArmor", ESM::Skill::HeavyArmor}, - {"SkillBluntWeapon", ESM::Skill::BluntWeapon}, - {"SkillLongBlade", ESM::Skill::LongBlade}, - {"SkillAxe", ESM::Skill::Axe}, - {"SkillSpear", ESM::Skill::Spear}, - {"SkillAthletics", ESM::Skill::Athletics}, - {"SkillEnchant", ESM::Skill::Armorer}, - {"SkillDestruction", ESM::Skill::Destruction}, - {"SkillAlteration", ESM::Skill::Alteration}, - {"SkillIllusion", ESM::Skill::Illusion}, - {"SkillConjuration", ESM::Skill::Conjuration}, - {"SkillMysticism", ESM::Skill::Mysticism}, - {"SkillRestoration", ESM::Skill::Restoration}, - {"SkillAlchemy", ESM::Skill::Alchemy}, - {"SkillUnarmored", ESM::Skill::Unarmored}, - {"SkillSecurity", ESM::Skill::Security}, - {"SkillSneak", ESM::Skill::Sneak}, - {"SkillAcrobatics", ESM::Skill::Acrobatics}, - {"SkillLightArmor", ESM::Skill::LightArmor}, - {"SkillShortBlade", ESM::Skill::ShortBlade}, - {"SkillMarksman", ESM::Skill::Marksman}, - {"SkillMercantile", ESM::Skill::Mercantile}, - {"SkillSpeechcraft", ESM::Skill::Speechcraft}, - {"SkillHandToHand", ESM::Skill::HandToHand}, - }; - for (size_t i = 0; i < sizeof(skillMap)/sizeof(skillMap[0]); ++i) - { - if (skillMap[i].id == id) - { - ESM::Skill::SkillEnum skillId = skillMap[i].skillId; - playerSkillValues[skillId] = value; - break; - } - } +void WindowManager::setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::Stat& value) +{ + stats->setValue(parSkill, value); + playerSkillValues[parSkill] = value; } void WindowManager::setValue (const std::string& id, const MWMechanics::DynamicStat& value) @@ -504,7 +464,7 @@ const std::string &WindowManager::getGameSettingString(const std::string &id, co return default_; } -void WindowManager::onNameDialogDone() +void WindowManager::onNameDialogDone(WindowBase* parWindow) { if (nameDialog) { @@ -513,18 +473,19 @@ void WindowManager::onNameDialogDone() removeDialog(nameDialog); } - bool goNext = nameChosen; // Go to next dialog if name was previously chosen - nameChosen = true; - - if (reviewNext) + // Go to next dialog if name was previously chosen + if (creationStage == ReviewNext) setGuiMode(GM_Review); - else if (goNext) + else if (creationStage >= NameChosen) setGuiMode(GM_Race); else + { + creationStage = NameChosen; setGuiMode(GM_Game); + } } -void WindowManager::onRaceDialogDone() +void WindowManager::onRaceDialogDone(WindowBase* parWindow) { if (raceDialog) { @@ -534,15 +495,16 @@ void WindowManager::onRaceDialogDone() removeDialog(raceDialog); } - bool goNext = raceChosen; // Go to next dialog if race was previously chosen - raceChosen = true; - - if (reviewNext) + // Go to next dialog if race was previously chosen + if (creationStage == ReviewNext) setGuiMode(GM_Review); - else if (goNext) + else if(creationStage >= RaceChosen) setGuiMode(GM_Class); else + { + creationStage = RaceChosen; setGuiMode(GM_Game); + } } void WindowManager::onDialogueWindowBye() @@ -568,29 +530,29 @@ void WindowManager::onRaceDialogBack() setGuiMode(GM_Name); } -void WindowManager::onClassChoice(MyGUI::WidgetPtr, int _index) +void WindowManager::onClassChoice(int _index) { if (classChoiceDialog) { removeDialog(classChoiceDialog); } - if (_index == ClassChoiceDialog::Class_Generate) - { - setGuiMode(GM_ClassGenerate); - } - else if (_index == ClassChoiceDialog::Class_Pick) + switch(_index) { - setGuiMode(GM_ClassPick); - } - else if (_index == ClassChoiceDialog::Class_Create) - { - setGuiMode(GM_ClassCreate); - } - else if (_index == ClassChoiceDialog::Class_Back) - { - setGuiMode(GM_Race); - } + case ClassChoiceDialog::Class_Generate: + setGuiMode(GM_ClassGenerate); + break; + case ClassChoiceDialog::Class_Pick: + setGuiMode(GM_ClassPick); + break; + case ClassChoiceDialog::Class_Create: + setGuiMode(GM_ClassCreate); + break; + case ClassChoiceDialog::Class_Back: + setGuiMode(GM_Race); + break; + + }; } namespace MWGui @@ -678,18 +640,6 @@ namespace MWGui } }; } -namespace MWGui -{ - - struct ClassPoint - { - const char *id; - // Specialization points to match, in order: Stealth, Combat, Magic - // Note: Order is taken from http://www.uesp.net/wiki/Morrowind:Class_Quiz - int points[3]; - }; -} - void WindowManager::showClassQuestionDialog() { if (generateClassStep == generateClassSteps.size()) @@ -753,7 +703,7 @@ void WindowManager::showClassQuestionDialog() if (generateClassResultDialog) removeDialog(generateClassResultDialog); - generateClassResultDialog = new GenerateClassResultDialog(environment); + generateClassResultDialog = new GenerateClassResultDialog(*this); generateClassResultDialog->setClassId(generateClass); generateClassResultDialog->eventBack = MyGUI::newDelegate(this, &WindowManager::onGenerateClassBack); generateClassResultDialog->eventDone = MyGUI::newDelegate(this, &WindowManager::onGenerateClassDone); @@ -769,7 +719,7 @@ void WindowManager::showClassQuestionDialog() if (generateClassQuestionDialog) removeDialog(generateClassQuestionDialog); - generateClassQuestionDialog = new InfoBoxDialog(environment); + generateClassQuestionDialog = new InfoBoxDialog(*this); InfoBoxDialog::ButtonList buttons; generateClassQuestionDialog->setText(generateClassSteps[generateClassStep].text); @@ -781,7 +731,7 @@ void WindowManager::showClassQuestionDialog() generateClassQuestionDialog->open(); } -void WindowManager::onClassQuestionChosen(MyGUI::Widget* _sender, int _index) +void WindowManager::onClassQuestionChosen(int _index) { if (generateClassQuestionDialog) removeDialog(generateClassQuestionDialog); @@ -804,7 +754,8 @@ void WindowManager::onClassQuestionChosen(MyGUI::Widget* _sender, int _index) void WindowManager::onGenerateClassBack() { - classChosen = true; + if(creationStage < ClassChosen) + creationStage = ClassChosen; if (generateClassResultDialog) removeDialog(generateClassResultDialog); @@ -813,25 +764,26 @@ void WindowManager::onGenerateClassBack() setGuiMode(GM_Class); } -void WindowManager::onGenerateClassDone() +void WindowManager::onGenerateClassDone(WindowBase* parWindow) { - bool goNext = classChosen; // Go to next dialog if class was previously chosen - classChosen = true; - if (generateClassResultDialog) removeDialog(generateClassResultDialog); environment.mMechanicsManager->setPlayerClass(generateClass); - if (reviewNext) + // Go to next dialog if class was previously chosen + if (creationStage == ReviewNext) setGuiMode(GM_Review); - else if (goNext) + else if (creationStage >= ClassChosen) setGuiMode(GM_Birth); else + { + creationStage = ClassChosen; setGuiMode(GM_Game); + } } -void WindowManager::onPickClassDialogDone() +void WindowManager::onPickClassDialogDone(WindowBase* parWindow) { if (pickClassDialog) { @@ -844,15 +796,16 @@ void WindowManager::onPickClassDialogDone() removeDialog(pickClassDialog); } - bool goNext = classChosen; // Go to next dialog if class was previously chosen - classChosen = true; - - if (reviewNext) + // Go to next dialog if class was previously chosen + if (creationStage == ReviewNext) setGuiMode(GM_Review); - else if (goNext) + else if (creationStage >= ClassChosen) setGuiMode(GM_Birth); else + { + creationStage = ClassChosen; setGuiMode(GM_Game); + } } void WindowManager::onPickClassDialogBack() @@ -868,7 +821,7 @@ void WindowManager::onPickClassDialogBack() setGuiMode(GM_Class); } -void WindowManager::onCreateClassDialogDone() +void WindowManager::onCreateClassDialogDone(WindowBase* parWindow) { if (createClassDialog) { @@ -898,15 +851,16 @@ void WindowManager::onCreateClassDialogDone() removeDialog(createClassDialog); } - bool goNext = classChosen; // Go to next dialog if class was previously chosen - classChosen = true; - - if (reviewNext) + // Go to next dialog if class was previously chosen + if (creationStage == ReviewNext) setGuiMode(GM_Review); - else if (goNext) + else if (creationStage >= ClassChosen) setGuiMode(GM_Birth); else + { + creationStage = ClassChosen; setGuiMode(GM_Game); + } } void WindowManager::onCreateClassDialogBack() @@ -917,7 +871,7 @@ void WindowManager::onCreateClassDialogBack() setGuiMode(GM_Class); } -void WindowManager::onBirthSignDialogDone() +void WindowManager::onBirthSignDialogDone(WindowBase* parWindow) { if (birthSignDialog) { @@ -927,13 +881,14 @@ void WindowManager::onBirthSignDialogDone() removeDialog(birthSignDialog); } - bool goNext = birthSignChosen; // Go to next dialog if birth sign was previously chosen - birthSignChosen = true; - - if (reviewNext || goNext) + // Go to next dialog if birth sign was previously chosen + if (creationStage >= BirthSignChosen) setGuiMode(GM_Review); else + { + creationStage = BirthSignChosen; setGuiMode(GM_Game); + } } void WindowManager::onBirthSignDialogBack() @@ -947,7 +902,7 @@ void WindowManager::onBirthSignDialogBack() setGuiMode(GM_Class); } -void WindowManager::onReviewDialogDone() +void WindowManager::onReviewDialogDone(WindowBase* parWindow) { if (reviewDialog) removeDialog(reviewDialog); @@ -963,38 +918,29 @@ void WindowManager::onReviewDialogBack() setGuiMode(GM_Birth); } -void WindowManager::onNameDialogActivate() -{ - if (reviewDialog) - removeDialog(reviewDialog); - - reviewNext = true; - setGuiMode(GM_Name); -} - -void WindowManager::onRaceDialogActivate() +void WindowManager::onReviewActivateDialog(int parDialog) { if (reviewDialog) removeDialog(reviewDialog); + creationStage = ReviewNext; - reviewNext = true; - setGuiMode(GM_Race); -} - -void WindowManager::onClassDialogActivate() -{ - if (reviewDialog) - removeDialog(reviewDialog); - - reviewNext = true; - setGuiMode(GM_Class); + switch(parDialog) + { + case ReviewDialog::NAME_DIALOG: + setGuiMode(GM_Name); + break; + case ReviewDialog::RACE_DIALOG: + setGuiMode(GM_Race); + break; + case ReviewDialog::CLASS_DIALOG: + setGuiMode(GM_Class); + break; + case ReviewDialog::BIRTHSIGN_DIALOG: + setGuiMode(GM_Birth); + }; } -void WindowManager::onBirthSignDialogActivate() +ESMS::ESMStore& WindowManager::getStore() { - if (reviewDialog) - removeDialog(reviewDialog); - - reviewNext = true; - setGuiMode(GM_Birth); + return environment.mWorld->getStore(); } diff --git a/apps/openmw/mwgui/window_manager.hpp b/apps/openmw/mwgui/window_manager.hpp index e39d9e6a63..1bf6204969 100644 --- a/apps/openmw/mwgui/window_manager.hpp +++ b/apps/openmw/mwgui/window_manager.hpp @@ -44,6 +44,7 @@ namespace OEngine namespace MWGui { + class WindowBase; class HUD; class MapWindow; class MainMenu; @@ -62,6 +63,14 @@ namespace MWGui class BirthDialog; class ReviewDialog; + struct ClassPoint + { + const char *id; + // Specialization points to match, in order: Stealth, Combat, Magic + // Note: Order is taken from http://www.uesp.net/wiki/Morrowind:Class_Quiz + unsigned int points[3]; + }; + class WindowManager { public: @@ -92,14 +101,6 @@ namespace MWGui BirthDialog *birthSignDialog; ReviewDialog *reviewDialog; - // Which dialogs have been shown, controls back/next/ok buttons - bool nameChosen; - bool raceChosen; - bool classChosen; - bool birthSignChosen; - bool reviewNext; - ///< If true then any click on Next will cause the summary to be shown - // Keeps track of current step in Generate Class dialogs unsigned generateClassStep; // A counter for each specialization which is increased when an answer is chosen, in order: Stealth, Combat, Magic @@ -153,10 +154,13 @@ namespace MWGui void setGuiMode(GuiMode newMode); + bool showFPSCounter; + float mFPS; + public: /// The constructor needs the main Gui object WindowManager(MyGUI::Gui *_gui, MWWorld::Environment& environment, - const Compiler::Extensions& extensions, bool newGame); + const Compiler::Extensions& extensions, bool fpsSwitch, bool newGame); virtual ~WindowManager(); /** @@ -197,10 +201,12 @@ namespace MWGui MyGUI::Gui* getGui() const { return gui; } + void wmSetFPS(float fps) { mFPS = fps; } + void setValue (const std::string& id, const MWMechanics::Stat& value); ///< Set value for the given ID. - void setValue (const std::string& id, const MWMechanics::Stat& value); + void setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::Stat& value); ///< Set value for the given ID. void setValue (const std::string& id, const MWMechanics::DynamicStat& value); @@ -251,45 +257,57 @@ namespace MWGui */ const std::string &getGameSettingString(const std::string &id, const std::string &default_); + ESMS::ESMStore& getStore(); + private: void onDialogueWindowBye(); // Character generation: Name dialog - void onNameDialogDone(); + void onNameDialogDone(WindowBase* parWindow); // Character generation: Race dialog - void onRaceDialogDone(); + void onRaceDialogDone(WindowBase* parWindow); void onRaceDialogBack(); // Character generation: Choose class process - void onClassChoice(MyGUI::Widget* _sender, int _index); + void onClassChoice(int _index); // Character generation: Generate Class void showClassQuestionDialog(); - void onClassQuestionChosen(MyGUI::Widget* _sender, int _index); + void onClassQuestionChosen(int _index); void onGenerateClassBack(); - void onGenerateClassDone(); + void onGenerateClassDone(WindowBase* parWindow); // Character generation: Pick Class dialog - void onPickClassDialogDone(); + void onPickClassDialogDone(WindowBase* parWindow); void onPickClassDialogBack(); // Character generation: Create Class dialog - void onCreateClassDialogDone(); + void onCreateClassDialogDone(WindowBase* parWindow); void onCreateClassDialogBack(); // Character generation: Birth sign dialog - void onBirthSignDialogDone(); + void onBirthSignDialogDone(WindowBase* parWindow); void onBirthSignDialogBack(); // Character generation: Review dialog - void onReviewDialogDone(); + void onReviewDialogDone(WindowBase* parWindow); void onReviewDialogBack(); - void onNameDialogActivate(); - void onRaceDialogActivate(); - void onClassDialogActivate(); - void onBirthSignDialogActivate(); + void onReviewActivateDialog(int parDialog); + + enum CreationStageEnum + { + NotStarted, + NameChosen, + RaceChosen, + ClassChosen, + BirthSignChosen, + ReviewNext + }; + + // Which state the character creating is in, controls back/next/ok buttons + CreationStageEnum creationStage; }; template diff --git a/apps/openmw/mwmechanics/mechanicsmanager.cpp b/apps/openmw/mwmechanics/mechanicsmanager.cpp index df0b5616c9..33093c24dd 100644 --- a/apps/openmw/mwmechanics/mechanicsmanager.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanager.cpp @@ -282,17 +282,6 @@ namespace MWMechanics "HBar", "MBar", "FBar" }; - static const char *skillNames[27] = - { - "SkillBlock", "SkillArmorer", "SkillMediumArmor", "SkillHeavyArmor", - "SkillBluntWeapon", "SkillLongBlade", "SkillAxe", "SkillSpear", - "SkillAthletics", "SkillEnchant", "SkillDestruction", "SkillAlteration", - "SkillIllusion", "SkillConjuration", "SkillMysticism", "SkillRestoration", - "SkillAlchemy", "SkillUnarmored", "SkillSecurity", "SkillSneak", - "SkillAcrobatics", "SkillLightArmor", "SkillShortBlade", "SkillMarksman", - "SkillMercantile", "SkillSpeechcraft", "SkillHandToHand", - }; - for (int i=0; i<8; ++i) { if (stats.mAttributes[i]!=mWatchedCreature.mAttributes[i]) @@ -315,16 +304,14 @@ namespace MWMechanics bool update = false; - for (int i=0; i<27; ++i) + //Loop over ESM::Skill::SkillEnum + for(int i = 0; i < 27; ++i) { - if (npcStats.mSkill[i]!=mWatchedNpc.mSkill[i]) + if(npcStats.mSkill[i] != mWatchedNpc.mSkill[i]) { update = true; - mWatchedNpc.mSkill[i] = npcStats.mSkill[i]; - - mEnvironment.mWindowManager->setValue (skillNames[i], npcStats.mSkill[i]); - + mEnvironment.mWindowManager->setValue((ESM::Skill::SkillEnum)i, npcStats.mSkill[i]); } } diff --git a/apps/openmw/path.cpp b/apps/openmw/path.cpp index 9de8158afd..e7dbc04715 100644 --- a/apps/openmw/path.cpp +++ b/apps/openmw/path.cpp @@ -13,7 +13,7 @@ std::string OMW::Path::getPath(PathTypeEnum parType, const std::string parApp, c if(parType == GLOBAL_CFG_PATH) { #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE - theBasePath = macBundlePath() + "/Contents/MacOS/"; //FIXME do we have global/local with OSX? + theBasePath = Ogre::macBundlePath() + "/Contents/MacOS/"; //FIXME do we have global/local with OSX? #elif OGRE_PLATFORM == OGRE_PLATFORM_LINUX theBasePath = "/etc/"+parApp+"/"; #else @@ -24,7 +24,7 @@ std::string OMW::Path::getPath(PathTypeEnum parType, const std::string parApp, c else { #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE - theBasePath = macBundlePath() + "/Contents/MacOS/"; //FIXME do we have global/local with OSX? + theBasePath = Ogre::macBundlePath() + "/Contents/MacOS/"; //FIXME do we have global/local with OSX? #elif OGRE_PLATFORM == OGRE_PLATFORM_LINUX const char* theDir; if ((theDir = getenv("OPENMW_HOME")) != NULL) diff --git a/apps/openmw/path.hpp b/apps/openmw/path.hpp index 719e454355..84ff9ecab3 100644 --- a/apps/openmw/path.hpp +++ b/apps/openmw/path.hpp @@ -4,6 +4,10 @@ #include #include +#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE +#include +#endif + namespace OMW { class Path diff --git a/components/esm/.gitignore b/components/esm/.gitignore deleted file mode 100644 index be5edceaaf..0000000000 --- a/components/esm/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -old -*.d diff --git a/components/esm/esm_reader.hpp b/components/esm/esm_reader.hpp index 927c3b0856..8f4fafd889 100644 --- a/components/esm/esm_reader.hpp +++ b/components/esm/esm_reader.hpp @@ -490,10 +490,6 @@ public: // Adjust number of record bytes left mCtx.leftRec -= mCtx.leftSub + 4; - - // Check that sizes added up - if(mCtx.leftRec < 0) - fail("Not enough bytes left in record for this subrecord."); } /** Get sub header and check the size diff --git a/components/esm_store/reclists.hpp b/components/esm_store/reclists.hpp index a03e325a91..4d67cf73d5 100644 --- a/components/esm_store/reclists.hpp +++ b/components/esm_store/reclists.hpp @@ -259,11 +259,11 @@ namespace ESMS int getSize() { return count; } // List of interior cells. Indexed by cell name. - typedef std::map IntCells; + typedef std::map IntCells; IntCells intCells; // List of exterior cells. Indexed as extCells[gridX][gridY]. - typedef std::map ExtCellsCol; + typedef std::map ExtCellsCol; typedef std::map ExtCells; ExtCells extCells; @@ -283,7 +283,7 @@ namespace ESMS } - const Cell* findInt(const std::string &id) const + const ESM::Cell* findInt(const std::string &id) const { IntCells::const_iterator it = intCells.find(id); @@ -293,7 +293,7 @@ namespace ESMS return it->second; } - const Cell *searchExt (int x, int y) const + const ESM::Cell *searchExt (int x, int y) const { ExtCells::const_iterator it = extCells.find (x); @@ -308,7 +308,7 @@ namespace ESMS return it2->second; } - const Cell *searchExtByName (const std::string& id) const + const ESM::Cell *searchExtByName (const std::string& id) const { for (ExtCells::const_iterator iter = extCells.begin(); iter!=extCells.end(); ++iter) { @@ -323,7 +323,7 @@ namespace ESMS return 0; } - const Cell *searchExtByRegion (const std::string& id) const + const ESM::Cell *searchExtByRegion (const std::string& id) const { std::string id2 = toLower (id); @@ -345,13 +345,13 @@ namespace ESMS count++; // All cells have a name record, even nameless exterior cells. - Cell *cell = new Cell; + ESM::Cell *cell = new ESM::Cell; cell->name = id; // The cell itself takes care of all the hairy details cell->load(esm); - if(cell->data.flags & Cell::Interior) + if(cell->data.flags & ESM::Cell::Interior) { // Store interior cell by name intCells[id] = cell; diff --git a/components/misc/fileops.cpp b/components/misc/fileops.cpp index ce514a736a..b7b9a8d781 100644 --- a/components/misc/fileops.cpp +++ b/components/misc/fileops.cpp @@ -2,32 +2,11 @@ #include #include +#include + bool isFile(const char *name) { boost::filesystem::path cfg_file_path(name); return boost::filesystem::exists(cfg_file_path); } -#ifdef __MACOSX__ -#include - -std::string macBundlePath() -{ - char path[1024]; - CFBundleRef mainBundle = CFBundleGetMainBundle(); - assert(mainBundle); - - CFURLRef mainBundleURL = CFBundleCopyBundleURL(mainBundle); - assert(mainBundleURL); - - CFStringRef cfStringRef = CFURLCopyFileSystemPath(mainBundleURL, kCFURLPOSIXPathStyle); - assert(cfStringRef); - - CFStringGetCString(cfStringRef, path, 1024, kCFStringEncodingASCII); - - CFRelease(mainBundleURL); - CFRelease(cfStringRef); - - return std::string(path); -} -#endif diff --git a/components/nifogre/ogre_nif_loader.cpp b/components/nifogre/ogre_nif_loader.cpp index 923c171db8..a33fde55ad 100644 --- a/components/nifogre/ogre_nif_loader.cpp +++ b/components/nifogre/ogre_nif_loader.cpp @@ -28,7 +28,6 @@ #include #include -#include "../../apps/openmw/mwclass/npc.hpp" #include "../nif/nif_file.hpp" #include "../nif/node.hpp" #include "../nif/data.hpp" @@ -476,8 +475,6 @@ static void vectorMul(const Matrix &A, float *C) void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bounds) { - //if( MWClass::Npc.isChest) - //cout << "t:" << shape << "\n"; assert(shape != NULL); // Interpret flags @@ -643,8 +640,13 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou for (std::vector::iterator it = boneList.begin(); it != boneList.end(); it++) { + if(mSkel.isNull()) + { + std::cout << "No skeleton for :" << shape->skin->bones[boneIndex].name.toString() << std::endl; + break; + } //get the bone from bones array of skindata - bonePtr = skel->getBone(shape->skin->bones[boneIndex].name.toString()); + bonePtr = mSkel->getBone(shape->skin->bones[boneIndex].name.toString()); // final_vector = old_vector + old_rotation*new_vector*old_scale vecPos = bonePtr->_getDerivedPosition() + @@ -767,7 +769,7 @@ void NIFLoader::handleNode(Nif::Node *node, int flags, //FIXME: "Bip01" isn't every time the root bone if (node->name == "Bip01" || node->name == "Root Bone") //root node, create a skeleton { - skel = SkeletonManager::getSingleton().create(getSkeletonName(), resourceGroup, true); + mSkel = SkeletonManager::getSingleton().create(getSkeletonName(), resourceGroup, true); /*if (node->extra->recType == RC_NiTextKeyExtraData ) { @@ -776,16 +778,16 @@ void NIFLoader::handleNode(Nif::Node *node, int flags, }*/ } - if (!skel.isNull()) //if there is a skeleton + if (!mSkel.isNull()) //if there is a skeleton { std::string name = node->name.toString(); //if (isBeast && isChest) // std::cout << "NAME: " << name << "\n"; // Quick-n-dirty workaround for the fact that several // bones may have the same name. - if(!skel->hasBone(name)) + if(!mSkel->hasBone(name)) { - bone = skel->createBone(name); + bone = mSkel->createBone(name); if (parentBone) parentBone->addChild(bone); @@ -1011,13 +1013,12 @@ void NIFLoader::loadResource(Resource *resource) //if(split== "Skins.NIF") // std::cout << "\nSPECIAL PROPS\n"; resourceName = ""; - MeshManager *m = MeshManager::getSingletonPtr(); // Check if the resource already exists //MeshPtr ptr = m->load(name, "custom"); //cout << "THISNAME: " << ptr->getName() << "\n"; //cout << "RESOURCE:"<< resource->getName(); mesh = 0; - skel.setNull(); + mSkel.setNull(); // Set up the VFS if it hasn't been done already if (!vfs) vfs = new OgreVFS(resourceGroup); diff --git a/components/nifogre/ogre_nif_loader.hpp b/components/nifogre/ogre_nif_loader.hpp index 18d511c96f..6ab22aa2fa 100644 --- a/components/nifogre/ogre_nif_loader.hpp +++ b/components/nifogre/ogre_nif_loader.hpp @@ -135,7 +135,7 @@ class NIFLoader : Ogre::ManualResourceLoader // pointer to the ogre mesh which is currently build Ogre::Mesh *mesh; - Ogre::SkeletonPtr skel; + Ogre::SkeletonPtr mSkel; }; #endif diff --git a/components/terrain/.gitignore b/components/terrain/.gitignore deleted file mode 100644 index 3367afdbbf..0000000000 --- a/components/terrain/.gitignore +++ /dev/null @@ -1 +0,0 @@ -old diff --git a/extern/caelum/src/Astronomy.cpp b/extern/caelum/src/Astronomy.cpp index 27ea934ecf..315b756fb2 100644 --- a/extern/caelum/src/Astronomy.cpp +++ b/extern/caelum/src/Astronomy.cpp @@ -321,7 +321,7 @@ namespace Caelum getGregorianDateTimeFromJulianDay(julianDay, year, month, day, hour, minute, second); } -#if (OGRE_PLATFORM == OGRE_PLATFORM_WIN32) && (OGRE_COMPILER == OGRE_COMPILER_MSVC) +#if (OGRE_PLATFORM == OGRE_PLATFORM_WIN32) && (OGRE_COMPILER == OGRE_COMPILER_MSVC) && (OGRE_ARCH_TYPE != OGRE_ARCHITECTURE_64) int Astronomy::enterHighPrecissionFloatingPointMode () { int oldMode = ::_controlfp (0, 0); diff --git a/extern/mygui_3.0.1/MyGUIEngine/CMakeLists.txt b/extern/mygui_3.0.1/MyGUIEngine/CMakeLists.txt index 5e1b24e62b..27362e0275 100644 --- a/extern/mygui_3.0.1/MyGUIEngine/CMakeLists.txt +++ b/extern/mygui_3.0.1/MyGUIEngine/CMakeLists.txt @@ -25,7 +25,10 @@ if (MYGUI_USE_FREETYPE) ) endif() -target_link_libraries(${PROJECT_NAME} ${CMAKE_DL_LIBS} uuid) +# We don't need this lib in OS X. uuid functions is in libc here. +if (NOT APPLE) + target_link_libraries(${PROJECT_NAME} ${CMAKE_DL_LIBS} uuid) +endif(NOT APPLE) if (MINGW) target_link_libraries(${PROJECT_NAME} libwinmm.a) diff --git a/extern/mygui_3.0.1/MyGUIEngine/src/MyGUI_ClipboardManager.cpp b/extern/mygui_3.0.1/MyGUIEngine/src/MyGUI_ClipboardManager.cpp index 810ddb568c..0de57f43d8 100644 --- a/extern/mygui_3.0.1/MyGUIEngine/src/MyGUI_ClipboardManager.cpp +++ b/extern/mygui_3.0.1/MyGUIEngine/src/MyGUI_ClipboardManager.cpp @@ -62,7 +62,11 @@ namespace MyGUI if (dwProcessID != ::GetCurrentProcessId()) return TRUE; +#ifdef _M_X64 + if (::GetWindowLongPtr(hWnd, GWLP_HINSTANCE) == lParam) +#else if (::GetWindowLong(hWnd, GWL_HINSTANCE) == lParam) +#endif { // Нашли. hWnd - то что надо g_hWnd = hWnd; diff --git a/extern/mygui_3.0.1/openmw_resources/openmw_hud_layout.xml b/extern/mygui_3.0.1/openmw_resources/openmw_hud_layout.xml index 22417b401a..8dc3cebab4 100644 --- a/extern/mygui_3.0.1/openmw_resources/openmw_hud_layout.xml +++ b/extern/mygui_3.0.1/openmw_resources/openmw_hud_layout.xml @@ -48,5 +48,13 @@ + + + + + + + diff --git a/extern/mygui_3.0.1/openmw_resources/openmw_text.skin.xml b/extern/mygui_3.0.1/openmw_resources/openmw_text.skin.xml index 66bf6cd10b..97c5cb3b28 100644 --- a/extern/mygui_3.0.1/openmw_resources/openmw_text.skin.xml +++ b/extern/mygui_3.0.1/openmw_resources/openmw_text.skin.xml @@ -9,6 +9,14 @@ + + + + + + + + diff --git a/files/mac/Info.plist b/files/mac/Info.plist index 77ec896182..6b350d2501 100644 --- a/files/mac/Info.plist +++ b/files/mac/Info.plist @@ -19,7 +19,7 @@ CFBundleSignature ???? CFBundleVersion - 0.07 + 0.10 CSResourcesFileMapped LSRequiresCarbon diff --git a/files/plugins.cfg.mac b/files/plugins.cfg.mac new file mode 100644 index 0000000000..9fe2798f7b --- /dev/null +++ b/files/plugins.cfg.mac @@ -0,0 +1,12 @@ +# Defines plugins to load + +# Define plugin folder +PluginFolder=${OGRE_PLUGIN_DIR} + +# Define plugins +Plugin=RenderSystem_GL.dylib +Plugin=Plugin_ParticleFX.dylib +Plugin=Plugin_OctreeSceneManager.dylib +# Plugin=Plugin_CgProgramManager + +