diff --git a/Bitstream Vera License.txt b/Bitstream Vera License.txt new file mode 100644 index 000000000..2b37cc1df --- /dev/null +++ b/Bitstream Vera License.txt @@ -0,0 +1,123 @@ +Bitstream Vera Fonts Copyright + +The fonts have a generous copyright, allowing derivative works (as +long as "Bitstream" or "Vera" are not in the names), and full +redistribution (so long as they are not *sold* by themselves). They +can be be bundled, redistributed and sold with any software. + +The fonts are distributed under the following copyright: + +Copyright +========= + +Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream +Vera is a trademark of Bitstream, Inc. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of the fonts accompanying this license ("Fonts") and associated +documentation files (the "Font Software"), to reproduce and distribute +the Font Software, including without limitation the rights to use, +copy, merge, publish, distribute, and/or sell copies of the Font +Software, and to permit persons to whom the Font Software is furnished +to do so, subject to the following conditions: + +The above copyright and trademark notices and this permission notice +shall be included in all copies of one or more of the Font Software +typefaces. + +The Font Software may be modified, altered, or added to, and in +particular the designs of glyphs or characters in the Fonts may be +modified and additional glyphs or characters may be added to the +Fonts, only if the fonts are renamed to names not containing either +the words "Bitstream" or the word "Vera". + +This License becomes null and void to the extent applicable to Fonts +or Font Software that has been modified and is distributed under the +"Bitstream Vera" names. + +The Font Software may be sold as part of a larger software package but +no copy of one or more of the Font Software typefaces may be sold by +itself. + +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL +BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, +OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT +SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. + +Except as contained in this notice, the names of Gnome, the Gnome +Foundation, and Bitstream Inc., shall not be used in advertising or +otherwise to promote the sale, use or other dealings in this Font +Software without prior written authorization from the Gnome Foundation +or Bitstream Inc., respectively. For further information, contact: +fonts at gnome dot org. + +Copyright FAQ +============= + + 1. I don't understand the resale restriction... What gives? + + Bitstream is giving away these fonts, but wishes to ensure its + competitors can't just drop the fonts as is into a font sale system + and sell them as is. It seems fair that if Bitstream can't make money + from the Bitstream Vera fonts, their competitors should not be able to + do so either. You can sell the fonts as part of any software package, + however. + + 2. I want to package these fonts separately for distribution and + sale as part of a larger software package or system. Can I do so? + + Yes. A RPM or Debian package is a "larger software package" to begin + with, and you aren't selling them independently by themselves. + See 1. above. + + 3. Are derivative works allowed? + Yes! + + 4. Can I change or add to the font(s)? + Yes, but you must change the name(s) of the font(s). + + 5. Under what terms are derivative works allowed? + + You must change the name(s) of the fonts. This is to ensure the + quality of the fonts, both to protect Bitstream and Gnome. We want to + ensure that if an application has opened a font specifically of these + names, it gets what it expects (though of course, using fontconfig, + substitutions could still could have occurred during font + opening). You must include the Bitstream copyright. Additional + copyrights can be added, as per copyright law. Happy Font Hacking! + + 6. If I have improvements for Bitstream Vera, is it possible they might get + adopted in future versions? + + Yes. The contract between the Gnome Foundation and Bitstream has + provisions for working with Bitstream to ensure quality additions to + the Bitstream Vera font family. Please contact us if you have such + additions. Note, that in general, we will want such additions for the + entire family, not just a single font, and that you'll have to keep + both Gnome and Jim Lyles, Vera's designer, happy! To make sense to add + glyphs to the font, they must be stylistically in keeping with Vera's + design. Vera cannot become a "ransom note" font. Jim Lyles will be + providing a document describing the design elements used in Vera, as a + guide and aid for people interested in contributing to Vera. + + 7. I want to sell a software package that uses these fonts: Can I do so? + + Sure. Bundle the fonts with your software and sell your software + with the fonts. That is the intent of the copyright. + + 8. If applications have built the names "Bitstream Vera" into them, + can I override this somehow to use fonts of my choosing? + + This depends on exact details of the software. Most open source + systems and software (e.g., Gnome, KDE, etc.) are now converting to + use fontconfig (see www.fontconfig.org) to handle font configuration, + selection and substitution; it has provisions for overriding font + names and subsituting alternatives. An example is provided by the + supplied local.conf file, which chooses the family Bitstream Vera for + "sans", "serif" and "monospace". Other software (e.g., the XFree86 + core server) has other mechanisms for font substitution. diff --git a/CMakeLists.txt b/CMakeLists.txt index 8ba9a5f0b..c565cf930 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,9 +4,6 @@ if (APPLE) set(APP_BUNDLE_NAME "${CMAKE_PROJECT_NAME}.app") set(APP_BUNDLE_DIR "${OpenMW_BINARY_DIR}/${APP_BUNDLE_NAME}") - - # using 10.6 sdk - set(CMAKE_OSX_SYSROOT "/Developer/SDKs/MacOSX10.6.sdk") endif (APPLE) # Macros @@ -27,11 +24,12 @@ set (OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VE configure_file ("${OpenMW_SOURCE_DIR}/Docs/mainpage.hpp.cmake" "${OpenMW_SOURCE_DIR}/Docs/mainpage.hpp") +option(MYGUI_STATIC "Link static build of Mygui into the binaries" FALSE) option(OGRE_STATIC "Link static build of Ogre and Ogre Plugins into the binaries" FALSE) # Sound source selection -option(USE_AUDIERE "use Audiere for sound" OFF) option(USE_FFMPEG "use ffmpeg for sound" OFF) +option(USE_AUDIERE "use audiere for sound" OFF) option(USE_MPG123 "use mpg123 + libsndfile for sound" ON) find_program(DPKG_PROGRAM dpkg DOC "dpkg program of Debian-based systems") @@ -124,54 +122,41 @@ set(OENGINE_BULLET ${LIBDIR}/openengine/bullet/trace.cpp ) -# Sound setup -if (USE_AUDIERE) - set(MANGLE_SOUND_OUTPUT - ${LIBDIR}/mangle/sound/sources/audiere_source.cpp - ${LIBDIR}/mangle/sound/sources/sample_reader.cpp - ${LIBDIR}/mangle/stream/clients/audiere_file.cpp) - find_package(Audiere REQUIRED) - set(SOUND_INPUT_INCLUDES ${AUDIERE_INCLUDE_DIR}) - set(SOUND_INPUT_LIBRARY ${AUDIERE_LIBRARY}) - set(SOUND_DEFINE -DOPENMW_USE_AUDIERE) -endif (USE_AUDIERE) +set(OENGINE_ALL ${OENGINE_OGRE} ${OENGINE_GUI} ${OENGINE_BULLET}) +source_group(libs\\openengine FILES ${OENGINE_ALL}) + +set(OPENMW_LIBS ${MANGLE_ALL} ${OENGINE_ALL}) +set(OPENMW_LIBS_HEADER) +# Sound setup +set(SOUND_INPUT_INCLUDES "") +set(SOUND_INPUT_LIBRARY "") +set(SOUND_DEFINE "") if (USE_FFMPEG) - set(MANGLE_SOUND_OUTPUT - ${LIBDIR}/mangle/sound/sources/ffmpeg_source.cpp) find_package(FFMPEG REQUIRED) - set(SOUND_INPUT_INCLUDES ${FFMPEG_INCLUDE_DIR}) - set(SOUND_INPUT_LIBRARY ${FFMPEG_LIBRARIES}) - set(SOUND_DEFINE -DOPENMW_USE_FFMPEG) + set(SOUND_INPUT_INCLUDES ${SOUND_INPUT_INCLUDES} ${FFMPEG_INCLUDE_DIR}) + set(SOUND_INPUT_LIBRARY ${SOUND_INPUT_LIBRARY} ${FFMPEG_LIBRARIES}) + set(SOUND_DEFINE ${SOUND_DEFINE} -DOPENMW_USE_FFMPEG) endif (USE_FFMPEG) +if (USE_AUDIERE) + find_package(Audiere REQUIRED) + set(SOUND_INPUT_INCLUDES ${SOUND_INPUT_INCLUDES} ${AUDIERE_INCLUDE_DIR}) + set(SOUND_INPUT_LIBRARY ${SOUND_INPUT_LIBRARY} ${AUDIERE_LIBRARY}) + set(SOUND_DEFINE ${SOUND_DEFINE} -DOPENMW_USE_AUDIERE) +endif (USE_AUDIERE) + if (USE_MPG123) - set(MANGLE_SOUND_OUTPUT - ${LIBDIR}/mangle/sound/sources/mpg123_source.cpp - ${LIBDIR}/mangle/sound/sources/libsndfile.cpp - ${LIBDIR}/mangle/sound/sources/sample_reader.cpp) find_package(MPG123 REQUIRED) find_package(SNDFILE REQUIRED) - set(SOUND_INPUT_INCLUDES ${MPG123_INCLUDE_DIR} ${SNDFILE_INCLUDE_DIR}) - set(SOUND_INPUT_LIBRARY ${MPG123_LIBRARY} ${SNDFILE_LIBRARY}) - set(SOUND_DEFINE -DOPENMW_USE_MPG123) + set(SOUND_INPUT_INCLUDES ${SOUND_INPUT_INCLUDES} ${MPG123_INCLUDE_DIR} ${SNDFILE_INCLUDE_DIR}) + set(SOUND_INPUT_LIBRARY ${SOUND_INPUT_LIBRARY} ${MPG123_LIBRARY} ${SNDFILE_LIBRARY}) + set(SOUND_DEFINE ${SOUND_DEFINE} -DOPENMW_USE_MPG123) endif (USE_MPG123) -set(OENGINE_SOUND - # Mangle and OEngine sound files are sort of intertwined, so put - # them together here - ${LIBDIR}/openengine/sound/sndmanager.cpp - ${LIBDIR}/mangle/sound/outputs/openal_out.cpp - ${MANGLE_SOUND_OUTPUT} -) -set(OENGINE_ALL ${OENGINE_OGRE} ${OENGINE_GUI} ${OENGINE_SOUND} ${OENGINE_BULLET}) -source_group(libs\\openengine FILES ${OENGINE_ALL}) - -set(OPENMW_LIBS ${MANGLE_ALL} ${OENGINE_ALL}) -set(OPENMW_LIBS_HEADER) - # Platform specific if (WIN32) + set(Boost_USE_STATIC_LIBS ON) set(PLATFORM_INCLUDE_DIR "platform") add_definitions(-DBOOST_ALL_NO_LIB) else (WIN32) @@ -181,7 +166,6 @@ include_directories(${UUID_INCLUDE_DIR}) endif (WIN32) if (MSVC10) set(PLATFORM_INCLUDE_DIR "") - add_definitions(-DMYGUI_DONT_REPLACE_NULLPTR) endif() if (APPLE) @@ -190,7 +174,13 @@ endif (APPLE) # Dependencies +# Fix for not visible pthreads functions for linker with glibc 2.15 +if (UNIX AND NOT APPLE) +find_package (Threads) +endif() + find_package(OGRE REQUIRED) +find_package(MyGUI REQUIRED) find_package(Boost REQUIRED COMPONENTS system filesystem program_options thread) find_package(OIS REQUIRED) find_package(OpenAL REQUIRED) @@ -205,16 +195,17 @@ ENDIF(WIN32) ENDIF(OGRE_STATIC) include_directories("." ${OGRE_INCLUDE_DIR} ${OGRE_INCLUDE_DIR}/Ogre ${OGRE_INCLUDE_DIR}/OGRE ${OGRE_PLUGIN_INCLUDE_DIRS} + ${OGRE_Terrain_INCLUDE_DIR} ${OIS_INCLUDE_DIRS} ${Boost_INCLUDE_DIR} ${PLATFORM_INCLUDE_DIR} - ${CMAKE_HOME_DIRECTORY}/extern/mygui_3.0.1/MyGUIEngine/include - ${CMAKE_HOME_DIRECTORY}/extern/mygui_3.0.1/OgrePlatform/include + ${MYGUI_INCLUDE_DIRS} + ${MYGUI_PLATFORM_INCLUDE_DIRS} ${OPENAL_INCLUDE_DIR} ${UUID_INCLUDE_DIR} ${LIBDIR} ) -link_directories(${Boost_LIBRARY_DIRS} ${OGRE_LIB_DIR}) +link_directories(${Boost_LIBRARY_DIRS} ${OGRE_LIB_DIR} ${MYGUI_LIB_DIR}) if(APPLE) # List used Ogre plugins @@ -224,14 +215,8 @@ if(APPLE) "Plugin_ParticleFX") endif(APPLE) -add_subdirectory( extern/mygui_3.0.1 ) - -# Make sure that certain libraries are used as static libraries -# This is in effect turns off __declspec (dllexport) for windows -# Each library will also need to be configured to build as a static lib - -# MyGUI: extern/mygui_3.0.0/ -add_definitions(-DMYGUI_STATIC) +add_subdirectory( files/) +add_subdirectory( files/mygui ) # Specify build paths @@ -243,6 +228,9 @@ endif (APPLE) # Other files +configure_file(${OpenMW_SOURCE_DIR}/files/settings-default.cfg + "${OpenMW_BINARY_DIR}/settings-default.cfg") + configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg.local "${OpenMW_BINARY_DIR}/openmw.cfg") configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg @@ -269,8 +257,14 @@ if (APPLE) "${APP_BUNDLE_DIR}/Contents/Resources/OpenMW.icns" COPYONLY) # prepare plugins - if (${CMAKE_BUILD_TYPE} MATCHES "Release" OR - ${CMAKE_BUILD_TYPE} MATCHES "RelWithDebugInfo") + if (${CMAKE_BUILD_TYPE} MATCHES "Release") + set(OPENMW_RELEASE_BUILD 1) + endif() + if (${CMAKE_BUILD_TYPE} MATCHES "RelWithDebugInfo") + set(OPENMW_RELEASE_BUILD 1) + endif() + + if (${OPENMW_RELEASE_BUILD}) set(OGRE_PLUGIN_DIR ${OGRE_PLUGIN_DIR_REL}) else() set(OGRE_PLUGIN_DIR ${OGRE_PLUGIN_DIR_DBG}) @@ -286,7 +280,16 @@ endif (APPLE) # Compiler settings if (CMAKE_COMPILER_IS_GNUCC) - add_definitions (-Wall -Wextra -Wno-unused-parameter -Wno-unused-but-set-parameter -Wno-reorder) + add_definitions (-Wall -Wextra -Wno-unused-parameter -Wno-reorder) + + # Silence warnings in OGRE headers. Remove once OGRE got fixed! + add_definitions (-Wno-ignored-qualifiers) + + execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion + OUTPUT_VARIABLE GCC_VERSION) + if ("${GCC_VERSION}" VERSION_GREATER 4.6 OR "${GCC_VERSION}" VERSION_EQUAL 4.6) + add_definitions (-Wno-unused-but-set-parameter) + endif("${GCC_VERSION}" VERSION_GREATER 4.6 OR "${GCC_VERSION}" VERSION_EQUAL 4.6) endif (CMAKE_COMPILER_IS_GNUCC) if(DPKG_PROGRAM) @@ -308,6 +311,7 @@ if(DPKG_PROGRAM) INSTALL(FILES "${OpenMW_SOURCE_DIR}/apps/launcher/resources/images/openmw.png" DESTINATION "share/pixmaps/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw") #Install global configuration files + INSTALL(FILES "${OpenMW_BINARY_DIR}/settings-default.cfg" DESTINATION "../etc/openmw/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw") INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" DESTINATION "../etc/openmw/" RENAME "openmw.cfg" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw") INSTALL(FILES "${OpenMW_BINARY_DIR}/plugins.cfg" DESTINATION "../etc/openmw/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw") @@ -325,8 +329,8 @@ if(DPKG_PROGRAM) Data files from the original game is required to run it.") SET(CPACK_DEBIAN_PACKAGE_NAME "openmw") SET(CPACK_DEBIAN_PACKAGE_VERSION "${VERSION_STRING}") - SET(CPACK_PACKAGE_EXECUTABLES "openmw;OpenMW esmtool;Esmtool omwlauncher;OMWLauncher") - SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libogre-1.7.3 (>= 1.7.3), libbullet0 (>= 2.77), libboost-filesystem1.46.1 (>= 1.46.1), libboost-program-options1.46.1 (>= 1.46.1), libboost-system1.46.1 (>= 1.46.1), libboost-thread1.46.1 (>= 1.46.1), libc6 (>= 2.11.2), libfreetype6 (>= 2.2.1), libgcc1 (>= 1:4.1.1), libmpg123-0 (>= 1.12.1), libois-1.3.0 (>= 1.3.0), libopenal1 (>= 1:1.12.854), libsndfile1 (>= 1.0.23), libstdc++6 (>= 4.4.5), libuuid1 (>= 2.17.2), libqtgui4 (>= 4.7.0)") + SET(CPACK_PACKAGE_EXECUTABLES "openmw;OpenMW esmtool;Esmtool omwlauncher;OMWLauncher mwiniimporter;MWiniImporter") + SET(CPACK_DEBIAN_PACKAGE_DEPENDS "nvidia-cg-toolkit (>= 2.1), libboost-filesystem1.46.1 (>= 1.46.1), libboost-program-options1.46.1 (>= 1.46.1), libboost-system1.46.1 (>= 1.46.1), libboost-thread1.46.1 (>= 1.46.1), libc6 (>= 2.11.2), libfreetype6 (>= 2.2.1), libgcc1 (>= 1:4.1.1), libmpg123-0 (>= 1.12.1), libois-1.3.0 (>= 1.3.0), libopenal1 (>= 1:1.12.854), libsndfile1 (>= 1.0.23), libstdc++6 (>= 4.4.5), libuuid1 (>= 2.17.2), libqtgui4 (>= 4.7.0)") SET(CPACK_DEBIAN_PACKAGE_SECTION "Games") @@ -346,6 +350,10 @@ if(WIN32) FILE(GLOB files "${OpenMW_BINARY_DIR}/Release/*.*") INSTALL(FILES ${files} DESTINATION ".") INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" DESTINATION "." RENAME "openmw.cfg") + INSTALL(FILES + "${OpenMW_SOURCE_DIR}/readme.txt" + "${OpenMW_BINARY_DIR}/settings-default.cfg" + DESTINATION ".") INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION ".") SET(CPACK_GENERATOR "NSIS") @@ -355,7 +363,12 @@ if(WIN32) SET(CPACK_PACKAGE_VERSION_MAJOR ${OPENMW_VERSION_MAJOR}) SET(CPACK_PACKAGE_VERSION_MINOR ${OPENMW_VERSION_MINO}) SET(CPACK_PACKAGE_VERSION_PATCH ${OPENMW_VERSION_RELEASE}) - SET(CPACK_PACKAGE_EXECUTABLES "openmw;OpenMW;esmtool;Esmtool;omwlauncher;OpenMW Launcher") + SET(CPACK_PACKAGE_EXECUTABLES "openmw;OpenMW;omwlauncher;OpenMW Launcher") + SET(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '\$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Readme.lnk' '\$INSTDIR\\\\readme.txt'") + SET(CPACK_NSIS_DELETE_ICONS_EXTRA " + !insertmacro MUI_STARTMENU_GETFOLDER Application $MUI_TEMP + Delete \\\"$SMPROGRAMS\\\\$MUI_TEMP\\\\Readme.lnk\\\" + ") SET(CPACK_PACKAGE_DESCRIPTION_FILE "${OpenMW_SOURCE_DIR}/readme.txt") SET(CPACK_RESOURCE_FILE_LICENSE "${OpenMW_SOURCE_DIR}/GPL3.txt") SET(CPACK_NSIS_EXECUTABLES_DIRECTORY ".") @@ -409,6 +422,11 @@ if (BUILD_LAUNCHER) add_subdirectory( apps/launcher ) endif() +option(BUILD_MWINIIMPORTER "build MWiniImporter inspector" ON) +if (BUILD_MWINIIMPORTER) + add_subdirectory( apps/mwiniimporter ) +endif() + if (WIN32) if (MSVC) if (USE_DEBUG_CONSOLE) @@ -498,6 +516,7 @@ if (APPLE) install(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" RENAME "openmw.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime) install(FILES "${OpenMW_BINARY_DIR}/plugins.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime) + install(FILES "${OpenMW_BINARY_DIR}/launcher.qss" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime) set(CPACK_GENERATOR "DragNDrop") set(CPACK_PACKAGE_VERSION ${OPENMW_VERSION}) diff --git a/OFL.txt b/OFL.txt new file mode 100644 index 000000000..043e85e83 --- /dev/null +++ b/OFL.txt @@ -0,0 +1,93 @@ +Copyright (c) 2010, 2011 Georg Duffner (http://www.georgduffner.at) + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/apps/launcher/CMakeLists.txt b/apps/launcher/CMakeLists.txt index fd736e011..ccefee1ee 100644 --- a/apps/launcher/CMakeLists.txt +++ b/apps/launcher/CMakeLists.txt @@ -95,5 +95,5 @@ else() "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/launcher.qss") configure_file(${CMAKE_SOURCE_DIR}/files/launcher.cfg - "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}launcher.cfg") + "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/launcher.cfg") endif() diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index 054cbf141..c15274e74 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -222,10 +222,10 @@ void DataFilesPage::setupDataFiles() QMessageBox msgBox; msgBox.setWindowTitle("Error detecting Morrowind installation"); - msgBox.setIcon(QMessageBox::Critical); + msgBox.setIcon(QMessageBox::Warning); msgBox.setStandardButtons(QMessageBox::Cancel); msgBox.setText(tr("
Could not find the Data Files location

\ - The directory containing the Data Files was not found.

\ + The directory containing the data files was not found.

\ Press \"Browse...\" to specify the location manually.
")); QAbstractButton *dirSelectButton = @@ -279,72 +279,79 @@ void DataFilesPage::setupDataFiles() const Files::MultiDirCollection &esp = fileCollections.getCollection(".esp"); for (Files::MultiDirCollection::TIter iter(esp.begin()); iter!=esp.end(); ++iter) { - ESMReader fileReader; - QStringList availableMasters; // Will contain all found masters - fileReader.setEncoding(variables["encoding"].as()); - fileReader.open(iter->second.string()); + try { + ESMReader fileReader; + QStringList availableMasters; // Will contain all found masters + + fileReader.setEncoding(variables["encoding"].as()); + fileReader.open(iter->second.string()); - // First we fill the availableMasters and the mMastersWidget - ESMReader::MasterList mlist = fileReader.getMasters(); + // First we fill the availableMasters and the mMastersWidget + ESMReader::MasterList mlist = fileReader.getMasters(); - for (unsigned int i = 0; i < mlist.size(); ++i) { - const QString currentMaster = QString::fromStdString(mlist[i].name); - availableMasters.append(currentMaster); + for (unsigned int i = 0; i < mlist.size(); ++i) { + const QString currentMaster = QString::fromStdString(mlist[i].name); + availableMasters.append(currentMaster); - const QList itemList = mMastersWidget->findItems(currentMaster, Qt::MatchExactly); + const QList itemList = mMastersWidget->findItems(currentMaster, Qt::MatchExactly); - if (itemList.isEmpty()) { // Master is not yet in the widget - mMastersWidget->insertRow(i); + if (itemList.isEmpty()) { // Master is not yet in the widget + mMastersWidget->insertRow(i); - QTableWidgetItem *item = new QTableWidgetItem(currentMaster); - item->setForeground(Qt::red); - item->setFlags(item->flags() & ~(Qt::ItemIsSelectable)); + QTableWidgetItem *item = new QTableWidgetItem(currentMaster); + item->setForeground(Qt::red); + item->setFlags(item->flags() & ~(Qt::ItemIsSelectable)); - mMastersWidget->setItem(i, 0, item); + mMastersWidget->setItem(i, 0, item); + } } - } - availableMasters.sort(); // Sort the masters alphabetically + availableMasters.sort(); // Sort the masters alphabetically - // Now we put the current plugin in the mDataFilesModel under its masters - QStandardItem *parent = new QStandardItem(availableMasters.join(",")); + // Now we put the current plugin in the mDataFilesModel under its masters + QStandardItem *parent = new QStandardItem(availableMasters.join(",")); - QString fileName = QString::fromStdString(boost::filesystem::path (iter->second.filename()).string()); - QStandardItem *child = new QStandardItem(fileName); + QString fileName = QString::fromStdString(boost::filesystem::path (iter->second.filename()).string()); + QStandardItem *child = new QStandardItem(fileName); - // Tooltip information - QString author = QString::fromStdString(fileReader.getAuthor()); - float version = fileReader.getFVer(); - QString description = QString::fromStdString(fileReader.getDesc()); + // Tooltip information + QString author = QString::fromStdString(fileReader.getAuthor()); + float version = fileReader.getFVer(); + QString description = QString::fromStdString(fileReader.getDesc()); - // For the date created/modified - QFileInfo fi(QString::fromStdString(iter->second.string())); + // For the date created/modified + QFileInfo fi(QString::fromStdString(iter->second.string())); - QString toolTip= QString("Author: %1
\ - Version: %2

\ - Description:
\ - %3

\ - Created on: %4
\ - Last modified: %5") - .arg(author) - .arg(version) - .arg(description) - .arg(fi.created().toString(Qt::TextDate)) - .arg(fi.lastModified().toString(Qt::TextDate)); + QString toolTip= QString("Author: %1
\ + Version: %2

\ + Description:
\ + %3

\ + Created on: %4
\ + Last modified: %5") + .arg(author) + .arg(version) + .arg(description) + .arg(fi.created().toString(Qt::TextDate)) + .arg(fi.lastModified().toString(Qt::TextDate)); - child->setToolTip(toolTip); + child->setToolTip(toolTip); - const QList masterList = mDataFilesModel->findItems(availableMasters.join(",")); + const QList masterList = mDataFilesModel->findItems(availableMasters.join(",")); - if (masterList.isEmpty()) { // Masters node not yet in the mDataFilesModel - parent->appendRow(child); - mDataFilesModel->appendRow(parent); - } else { - // Masters node exists, append current plugin - foreach (QStandardItem *currentItem, masterList) { - currentItem->appendRow(child); + if (masterList.isEmpty()) { // Masters node not yet in the mDataFilesModel + parent->appendRow(child); + mDataFilesModel->appendRow(parent); + } else { + // Masters node exists, append current plugin + foreach (QStandardItem *currentItem, masterList) { + currentItem->appendRow(child); + } } + + } catch(std::runtime_error &e) { + // An error occurred while reading the .esp + continue; } } @@ -1050,16 +1057,8 @@ void DataFilesPage::writeConfig(QString profile) return; } - // Prepare the OpenMW config - QString config = QString::fromStdString((mCfgMgr.getLocalPath() / "openmw.cfg").string()); - QFile file(config); - - if (!file.exists()) { - config = QString::fromStdString((mCfgMgr.getUserPath() / "openmw.cfg").string()); - } - - // Open the config as a QFile - file.setFileName(config); + // Open the OpenMW config as a QFile + QFile file(QString::fromStdString((mCfgMgr.getUserPath() / "openmw.cfg").string())); if (!file.open(QIODevice::ReadWrite | QIODevice::Text)) { // File cannot be opened or created diff --git a/apps/launcher/maindialog.cpp b/apps/launcher/maindialog.cpp index 49c0bd960..8bb618dd6 100644 --- a/apps/launcher/maindialog.cpp +++ b/apps/launcher/maindialog.cpp @@ -45,9 +45,28 @@ MainDialog::MainDialog() setWindowFlags(this->windowFlags() & ~Qt::WindowContextHelpButtonHint); setMinimumSize(QSize(575, 575)); + // Install the stylesheet font + QFile file; + QFontDatabase fontDatabase; + + const QStringList fonts = fontDatabase.families(); + + // Check if the font is installed + if (!fonts.contains("EB Garamond")) { + + QString font = QString::fromStdString((mCfgMgr.getGlobalDataPath() / "resources/mygui/EBGaramond-Regular.ttf").string()); + file.setFileName(font); + + if (!file.exists()) { + font = QString::fromStdString((mCfgMgr.getLocalPath() / "resources/mygui/EBGaramond-Regular.ttf").string()); + } + + fontDatabase.addApplicationFont(font); + } + // Load the stylesheet QString config = QString::fromStdString((mCfgMgr.getGlobalDataPath() / "resources/launcher.qss").string()); - QFile file(config); + file.setFileName(config); if (!file.exists()) { file.setFileName(QString::fromStdString((mCfgMgr.getLocalPath() / "launcher.qss").string())); @@ -175,6 +194,7 @@ void MainDialog::play() QDir dir(QCoreApplication::applicationDirPath()); QString game = dir.absoluteFilePath("openmw"); QFile file(game); + game = "\"" + game + "\""; #else QString game = "./openmw"; QFile file(game); diff --git a/apps/launcher/resources/images/openmw-header.png b/apps/launcher/resources/images/openmw-header.png index a168d4d2a..a2ffab68b 100644 Binary files a/apps/launcher/resources/images/openmw-header.png and b/apps/launcher/resources/images/openmw-header.png differ diff --git a/apps/mwiniimporter/CMakeLists.txt b/apps/mwiniimporter/CMakeLists.txt new file mode 100644 index 000000000..2a8c0f5fe --- /dev/null +++ b/apps/mwiniimporter/CMakeLists.txt @@ -0,0 +1,20 @@ +set(MWINIIMPORT + main.cpp + importer.cpp +) + +set(MWINIIMPORT_HEADER + importer.hpp +) + +source_group(launcher FILES ${MWINIIMPORT} ${MWINIIMPORT_HEADER}) + +add_executable(mwiniimport + ${MWINIIMPORT} +) + +target_link_libraries(mwiniimport + ${Boost_LIBRARIES} + components +) + diff --git a/apps/mwiniimporter/importer.cpp b/apps/mwiniimporter/importer.cpp new file mode 100644 index 000000000..5503a7c1a --- /dev/null +++ b/apps/mwiniimporter/importer.cpp @@ -0,0 +1,216 @@ +#include "importer.hpp" +#include +#include +#include +#include +#include +#include +#include +#include + +MwIniImporter::MwIniImporter() { + const char *map[][2] = + { + { "fps", "General:Show FPS" }, + { "nosound", "General:Disable Audio" }, + { 0, 0 } + }; + const char *fallback[] = { + "Weather:Sunrise Time", + "Weather:Sunset Time", + 0 + }; + + for(int i=0; map[i][0]; i++) { + mMergeMap.insert(std::make_pair(map[i][0], map[i][1])); + } + + for(int i=0; fallback[i]; i++) { + mMergeFallback.push_back(fallback[i]); + } +} + +void MwIniImporter::setVerbose(bool verbose) { + mVerbose = verbose; +} + +std::string MwIniImporter::numberToString(int n) { + std::stringstream str; + str << n; + return str.str(); +} + +MwIniImporter::multistrmap MwIniImporter::loadIniFile(std::string filename) { + std::cout << "load ini file: " << filename << std::endl; + + std::string section(""); + MwIniImporter::multistrmap map; + boost::iostreams::streamfile(filename.c_str()); + + std::string line; + while (std::getline(file, line)) { + + if(line[0] == '[') { + if(line.length() > 2) { + section = line.substr(1, line.length()-3); + } + continue; + } + + int comment_pos = line.find(";"); + if(comment_pos > 0) { + line = line.substr(0,comment_pos); + } + + if(line.empty()) { + continue; + } + + int pos = line.find("="); + if(pos < 1) { + continue; + } + + std::string key(section + ":" + line.substr(0,pos)); + std::string value(line.substr(pos+1)); + + multistrmap::iterator it; + if((it = map.find(key)) == map.end()) { + map.insert( std::make_pair > (key, std::vector() ) ); + } + map[key].push_back(value); + } + + return map; +} + +MwIniImporter::multistrmap MwIniImporter::loadCfgFile(std::string filename) { + std::cout << "load cfg file: " << filename << std::endl; + + MwIniImporter::multistrmap map; + boost::iostreams::streamfile(filename.c_str()); + + std::string line; + while (std::getline(file, line)) { + + // we cant say comment by only looking at first char anymore + int comment_pos = line.find("#"); + if(comment_pos > 0) { + line = line.substr(0,comment_pos); + } + + if(line.empty()) { + continue; + } + + int pos = line.find("="); + if(pos < 1) { + continue; + } + + std::string key(line.substr(0,pos)); + std::string value(line.substr(pos+1)); + + multistrmap::iterator it; + if((it = map.find(key)) == map.end()) { + map.insert( std::make_pair > (key, std::vector() ) ); + } + map[key].push_back(value); + } + + return map; +} + +void MwIniImporter::merge(multistrmap &cfg, multistrmap &ini) { + multistrmap::iterator cfgIt; + multistrmap::iterator iniIt; + for(strmap::iterator it=mMergeMap.begin(); it!=mMergeMap.end(); it++) { + if((iniIt = ini.find(it->second)) != ini.end()) { + for(std::vector::iterator vc = iniIt->second.begin(); vc != iniIt->second.end(); vc++) { + cfg.erase(it->first); + insertMultistrmap(cfg, it->first, *vc); + } + } + } +} + +void MwIniImporter::mergeFallback(multistrmap &cfg, multistrmap &ini) { + cfg.erase("fallback"); + + multistrmap::iterator cfgIt; + multistrmap::iterator iniIt; + for(std::vector::iterator it=mMergeFallback.begin(); it!=mMergeFallback.end(); it++) { + if((iniIt = ini.find(*it)) != ini.end()) { + for(std::vector::iterator vc = iniIt->second.begin(); vc != iniIt->second.end(); vc++) { + std::string value(*it); + std::replace( value.begin(), value.end(), ' ', '_' ); + std::replace( value.begin(), value.end(), ':', '_' ); + value.append(",").append(vc->substr(0,vc->length()-1)); + insertMultistrmap(cfg, "fallback", value); + } + } + } +}; + +void MwIniImporter::insertMultistrmap(multistrmap &cfg, std::string key, std::string value) { + multistrmap::iterator it = cfg.find(key); + if(it == cfg.end()) { + cfg.insert(std::make_pair >(key, std::vector() )); + } + cfg[key].push_back(value); +} + +void MwIniImporter::importGameFiles(multistrmap &cfg, multistrmap &ini) { + std::vector esmFiles; + std::vector espFiles; + std::string baseGameFile("Game Files:GameFile"); + std::string gameFile(""); + + multistrmap::iterator it = ini.begin(); + for(int i=0; it != ini.end(); i++) { + gameFile = baseGameFile; + gameFile.append(this->numberToString(i)); + + it = ini.find(gameFile); + if(it == ini.end()) { + break; + } + + for(std::vector::iterator entry = it->second.begin(); entry!=it->second.end(); entry++) { + std::string filetype(entry->substr(entry->length()-4, 3)); + std::transform(filetype.begin(), filetype.end(), filetype.begin(), ::tolower); + + if(filetype.compare("esm") == 0) { + esmFiles.push_back(*entry); + } + else if(filetype.compare("esp") == 0) { + espFiles.push_back(*entry); + } + } + + gameFile = ""; + } + + cfg.erase("master"); + cfg.insert( std::make_pair > ("master", std::vector() ) ); + + for(std::vector::iterator it=esmFiles.begin(); it!=esmFiles.end(); it++) { + cfg["master"].push_back(*it); + } + + cfg.erase("plugin"); + cfg.insert( std::make_pair > ("plugin", std::vector() ) ); + + for(std::vector::iterator it=espFiles.begin(); it!=espFiles.end(); it++) { + cfg["plugin"].push_back(*it); + } +} + +void MwIniImporter::writeToFile(boost::iostreams::stream &out, multistrmap &cfg) { + + for(multistrmap::iterator it=cfg.begin(); it != cfg.end(); it++) { + for(std::vector::iterator entry=it->second.begin(); entry != it->second.end(); entry++) { + out << (it->first) << "=" << (*entry) << std::endl; + } + } +} diff --git a/apps/mwiniimporter/importer.hpp b/apps/mwiniimporter/importer.hpp new file mode 100644 index 000000000..ced332a72 --- /dev/null +++ b/apps/mwiniimporter/importer.hpp @@ -0,0 +1,34 @@ +#ifndef MWINIIMPORTER_IMPORTER +#define MWINIIMPORTER_IMPORTER 1 + +#include +#include +#include +#include +#include +#include + +class MwIniImporter { + public: + typedef std::map strmap; + typedef std::map > multistrmap; + + MwIniImporter(); + void setVerbose(bool verbose); + multistrmap loadIniFile(std::string filename); + multistrmap loadCfgFile(std::string filename); + void merge(multistrmap &cfg, multistrmap &ini); + void mergeFallback(multistrmap &cfg, multistrmap &ini); + void importGameFiles(multistrmap &cfg, multistrmap &ini); + void writeToFile(boost::iostreams::stream &out, multistrmap &cfg); + + private: + void insertMultistrmap(multistrmap &cfg, std::string key, std::string value); + std::string numberToString(int n); + bool mVerbose; + strmap mMergeMap; + std::vector mMergeFallback; +}; + + +#endif diff --git a/apps/mwiniimporter/main.cpp b/apps/mwiniimporter/main.cpp new file mode 100644 index 000000000..234d7d57d --- /dev/null +++ b/apps/mwiniimporter/main.cpp @@ -0,0 +1,75 @@ +#include "importer.hpp" + +#include +#include +#include +#include + +namespace bpo = boost::program_options; + +int main(int argc, char *argv[]) { + + bpo::options_description desc("Syntax: mwiniimporter inifile configfile\nAllowed options"); + bpo::positional_options_description p_desc; + desc.add_options() + ("help,h", "produce help message") + ("verbose,v", "verbose output") + ("ini,i", bpo::value(), "morrowind.ini file") + ("cfg,c", bpo::value(), "openmw.cfg file") + ("output,o", bpo::value()->default_value(""), "openmw.cfg file") + ("game-files,g", "import esm and esp files") + ; + p_desc.add("ini", 1).add("cfg", 1); + + bpo::variables_map vm; + bpo::parsed_options parsed = bpo::command_line_parser(argc, argv) + .options(desc) + .positional(p_desc) + .run(); + + bpo::store(parsed, vm); + + if(vm.count("help") || !vm.count("ini") || !vm.count("cfg")) { + std::cout << desc; + return 0; + } + + bpo::notify(vm); + + std::string iniFile = vm["ini"].as(); + std::string cfgFile = vm["cfg"].as(); + + // if no output is given, write back to cfg file + std::string outputFile(vm["output"].as()); + if(vm["output"].defaulted()) { + outputFile = vm["cfg"].as(); + } + + if(!boost::filesystem::exists(iniFile)) { + std::cerr << "ini file does not exist" << std::endl; + return -3; + } + if(!boost::filesystem::exists(cfgFile)) { + std::cerr << "cfg file does not exist" << std::endl; + return -4; + } + + MwIniImporter importer; + importer.setVerbose(vm.count("verbose")); + + MwIniImporter::multistrmap ini = importer.loadIniFile(iniFile); + MwIniImporter::multistrmap cfg = importer.loadCfgFile(cfgFile); + + importer.merge(cfg, ini); + importer.mergeFallback(cfg, ini); + + if(vm.count("game-files")) { + importer.importGameFiles(cfg, ini); + } + + std::cout << "write to: " << outputFile << std::endl; + boost::iostreams::stream file(outputFile); + importer.writeToFile(file, cfg); + + return 0; +} diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 6d33298df..2342882e0 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -14,7 +14,8 @@ set(GAME_HEADER source_group(game FILES ${GAME} ${GAME_HEADER}) add_openmw_dir (mwrender - renderingmanager debugging sky player animation npcanimation creatureanimation actors objects renderinginterface + renderingmanager debugging sky player animation npcanimation creatureanimation actors objects + renderinginterface localmap occlusionquery terrain terrainmaterial water ) add_openmw_dir (mwinput @@ -24,6 +25,7 @@ add_openmw_dir (mwinput add_openmw_dir (mwgui layouts text_input widgets race class birth review window_manager console dialogue dialogue_history window_base stats_window messagebox journalwindow charactercreation + map_window window_pinnable_base ) add_openmw_dir (mwdialogue @@ -38,13 +40,13 @@ add_openmw_dir (mwscript ) add_openmw_dir (mwsound - soundmanager + soundmanager openal_output audiere_decoder mpgsnd_decoder ffmpeg_decoder ) add_openmw_dir (mwworld refdata world physicssystem scene environment globals class action nullaction actionteleport containerstore actiontalk actiontake manualref player cellfunctors - cells localscripts customdata weather inventorystore + cells localscripts customdata weather inventorystore ptr ) add_openmw_dir (mwclass @@ -53,7 +55,7 @@ add_openmw_dir (mwclass ) add_openmw_dir (mwmechanics - mechanicsmanager stat creaturestats magiceffects movement + mechanicsmanager stat creaturestats magiceffects movement actors ) # Main executable @@ -81,17 +83,23 @@ add_definitions(${SOUND_DEFINE}) target_link_libraries(openmw ${OGRE_LIBRARIES} - ${OGRE_STATIC_PLUGINS} + ${OGRE_Terrain_LIBRARY} + ${OGRE_STATIC_PLUGINS} ${OIS_LIBRARIES} ${Boost_LIBRARIES} ${OPENAL_LIBRARY} ${SOUND_INPUT_LIBRARY} ${BULLET_LIBRARIES} + ${MYGUI_LIBRARIES} + ${MYGUI_PLATFORM_LIBRARIES} components - MyGUIEngine - MyGUIOgrePlatform ) +# Fix for not visible pthreads functions for linker with glibc 2.15 +if (UNIX AND NOT APPLE) +target_link_libraries(openmw ${CMAKE_THREAD_LIBS_INIT}) +endif() + if(APPLE) find_library(CARBON_FRAMEWORK Carbon) target_link_libraries(openmw ${CARBON_FRAMEWORK}) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 89068ce53..97aaf4090 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -82,12 +83,20 @@ void OMW::Engine::updateFocusReport (float duration) if (!handle.empty()) { - MWWorld::Ptr ptr = mEnvironment.mWorld->getPtrViaHandle (handle); + // the faced handle is not updated immediately, so on a cell change it might + // point to an object that doesn't exist anymore + // therefore, we are catching the "Unknown Ogre handle" exception that occurs in this case + try + { + MWWorld::Ptr ptr = mEnvironment.mWorld->getPtrViaHandle (handle); - if (!ptr.isEmpty()){ - name = MWWorld::Class::get (ptr).getName (ptr); + if (!ptr.isEmpty()){ + name = MWWorld::Class::get (ptr).getName (ptr); + } } + catch (std::runtime_error& e) + {} } if (name!=mFocusName) @@ -115,13 +124,12 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt) { mEnvironment.mFrameDuration = evt.timeSinceLastFrame; + // update input + mEnvironment.mInputManager->update(); + // sound if (mUseSound) - { - mEnvironment.mSoundManager->playPlaylist(); - mEnvironment.mSoundManager->update (evt.timeSinceLastFrame); - } // update GUI Ogre::RenderWindow* window = mOgre->getWindow(); @@ -152,7 +160,8 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt) // update actors std::vector > movement; - mEnvironment.mMechanicsManager->update (movement); + mEnvironment.mMechanicsManager->update (movement, mEnvironment.mFrameDuration, + mEnvironment.mWindowManager->getMode()!=MWGui::GM_Game); if (mEnvironment.mWindowManager->getMode()==MWGui::GM_Game) mEnvironment.mWorld->doPhysics (movement, mEnvironment.mFrameDuration); @@ -208,13 +217,18 @@ OMW::Engine::~Engine() void OMW::Engine::loadBSA() { const Files::MultiDirCollection& bsa = mFileCollections.getCollection (".bsa"); - std::string dataDirectory; + for (Files::MultiDirCollection::TIter iter(bsa.begin()); iter!=bsa.end(); ++iter) { std::cout << "Adding " << iter->second.string() << std::endl; Bsa::addBSA(iter->second.string()); + } - dataDirectory = iter->second.parent_path().string(); + const Files::PathContainer& dataDirs = mFileCollections.getPaths(); + std::string dataDirectory; + for (Files::PathContainer::const_iterator iter = dataDirs.begin(); iter != dataDirs.end(); ++iter) + { + dataDirectory = iter->string(); std::cout << "Data dir " << dataDirectory << std::endl; Bsa::addDir(dataDirectory, mFSStrict); } @@ -312,6 +326,29 @@ void OMW::Engine::go() { boost::filesystem::create_directories(configPath); } + + // Create the settings manager and load default settings file + Settings::Manager settings; + const std::string localdefault = mCfgMgr.getLocalPath().string() + "/settings-default.cfg"; + const std::string globaldefault = mCfgMgr.getGlobalPath().string() + "/settings-default.cfg"; + + // prefer local + if (boost::filesystem::exists(localdefault)) + settings.loadDefault(localdefault); + else if (boost::filesystem::exists(globaldefault)) + settings.loadDefault(globaldefault); + + // load user settings if they exist, otherwise just load the default settings as user settings + const std::string settingspath = mCfgMgr.getUserPath().string() + "/settings.cfg"; + if (boost::filesystem::exists(settingspath)) + settings.loadUser(settingspath); + else if (boost::filesystem::exists(localdefault)) + settings.loadUser(localdefault); + else if (boost::filesystem::exists(globaldefault)) + settings.loadUser(globaldefault); + + mFpsLevel = settings.getInt("fps", "HUD"); + mOgre->configure(!boost::filesystem::is_regular_file(mCfgMgr.getOgreConfigPath()), mCfgMgr.getOgreConfigPath().string(), mCfgMgr.getLogPath().string(), @@ -319,7 +356,11 @@ void OMW::Engine::go() // This has to be added BEFORE MyGUI is initialized, as it needs // to find core.xml here. + + //addResourcesDirectory(mResDir); + addResourcesDirectory(mResDir / "mygui"); + addResourcesDirectory(mResDir / "water"); // Create the window mOgre->createWindow("OpenMW"); @@ -328,7 +369,7 @@ void OMW::Engine::go() // Create the world mEnvironment.mWorld = new MWWorld::World (*mOgre, mFileCollections, mMaster, - mResDir, mNewGame, mEnvironment, mEncoding); + mResDir, mNewGame, mEnvironment, mEncoding, mFallbackMap); // Create window manager - this manages all the MW-specific GUI windows MWScript::registerExtensions (mExtensions); @@ -337,10 +378,7 @@ void OMW::Engine::go() mExtensions, mFpsLevel, mNewGame, mOgre, mCfgMgr.getLogPath().string() + std::string("/")); // Create sound system - mEnvironment.mSoundManager = new MWSound::SoundManager(mOgre->getRoot(), - mOgre->getCamera(), - mDataDirs, - mUseSound, mFSStrict, mEnvironment); + mEnvironment.mSoundManager = new MWSound::SoundManager(mUseSound, mEnvironment); // Create script system mScriptContext = new MWScript::CompilerContext (MWScript::CompilerContext::Type_Full, @@ -405,6 +443,9 @@ void OMW::Engine::go() // Start the main rendering loop mOgre->start(); + // Save user settings + settings.saveUser(settingspath); + std::cout << "Quitting peacefully.\n"; } @@ -418,10 +459,21 @@ void OMW::Engine::activate() if (handle.empty()) return; - MWWorld::Ptr ptr = mEnvironment.mWorld->getPtrViaHandle (handle); + // the faced handle is not updated immediately, so on a cell change it might + // point to an object that doesn't exist anymore + // therefore, we are catching the "Unknown Ogre handle" exception that occurs in this case + MWWorld::Ptr ptr; + try + { + ptr = mEnvironment.mWorld->getPtrViaHandle (handle); - if (ptr.isEmpty()) + if (ptr.isEmpty()) + return; + } + catch (std::runtime_error&) + { return; + } MWScript::InterpreterContext interpreterContext (mEnvironment, &ptr.getRefData().getLocals(), ptr); @@ -487,3 +539,8 @@ void OMW::Engine::setEncoding(const std::string& encoding) { mEncoding = encoding; } + +void OMW::Engine::setFallbackValues(std::map fallbackMap) +{ + mFallbackMap = fallbackMap; +} diff --git a/apps/openmw/engine.hpp b/apps/openmw/engine.hpp index 690430784..6eae20cc0 100644 --- a/apps/openmw/engine.hpp +++ b/apps/openmw/engine.hpp @@ -76,6 +76,7 @@ namespace OMW bool mReportFocus; float mFocusTDiff; std::string mFocusName; + std::map mFallbackMap; MWWorld::Environment mEnvironment; Compiler::Extensions mExtensions; @@ -163,6 +164,8 @@ namespace OMW void setAnimationVerbose(bool animverbose); + void setFallbackValues(std::map map); + private: Files::ConfigurationManager& mCfgMgr; }; diff --git a/apps/openmw/main.cpp b/apps/openmw/main.cpp index cd1e0e26e..df52faab1 100644 --- a/apps/openmw/main.cpp +++ b/apps/openmw/main.cpp @@ -54,6 +54,41 @@ inline boost::filesystem::path lexical_cast mMap; +}; + +void validate(boost::any &v, std::vector const &tokens, FallbackMap*, int) +{ + if(v.empty()) + { + v = boost::any(FallbackMap()); + } + + FallbackMap *map = boost::any_cast(&v); + + std::map::iterator mapIt; + for(std::vector::const_iterator it=tokens.begin(); it != tokens.end(); it++) + { + int sep = it->find(","); + if(sep < 1 || sep == (int)it->length()-1) +#if (BOOST_VERSION < 104200) + throw boost::program_options::validation_error("invalid value"); +#else + throw boost::program_options::validation_error(boost::program_options::validation_error::invalid_option_value); +#endif + + std::string key(it->substr(0,sep)); + std::string value(it->substr(sep+1)); + + if((mapIt = map->mMap.find(key)) == map->mMap.end()) + { + map->mMap.insert(std::make_pair(key,value)); + } + } +} + + /** * \brief Parses application command line and calls \ref Cfg::ConfigurationManager * to parse configuration files. @@ -92,39 +127,40 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat ("plugin", bpo::value()->default_value(StringsVector(), "") ->multitoken(), "plugin file(s)") - ("fps", boost::program_options::value()->implicit_value(1) - ->default_value(0), "fps counter detail (0 = off, 1 = fps counter, 2 = full detail)") - - ("anim-verbose", boost::program_options::value()->implicit_value(true) + ("anim-verbose", bpo::value()->implicit_value(true) ->default_value(false), "output animation indices files") - ("debug", boost::program_options::value()->implicit_value(true) + ("debug", bpo::value()->implicit_value(true) ->default_value(false), "debug mode") - ("nosound", boost::program_options::value()->implicit_value(true) + ("nosound", bpo::value()->implicit_value(true) ->default_value(false), "disable all sounds") - ("script-verbose", boost::program_options::value()->implicit_value(true) + ("script-verbose", bpo::value()->implicit_value(true) ->default_value(false), "verbose script output") - ("new-game", boost::program_options::value()->implicit_value(true) + ("new-game", bpo::value()->implicit_value(true) ->default_value(false), "activate char gen/new game mechanics") - ("script-all", boost::program_options::value()->implicit_value(true) + ("script-all", bpo::value()->implicit_value(true) ->default_value(false), "compile all scripts (excluding dialogue scripts) at startup") - ("fs-strict", boost::program_options::value()->implicit_value(true) + ("fs-strict", bpo::value()->implicit_value(true) ->default_value(false), "strict file system handling (no case folding)") - ( "encoding", boost::program_options::value()-> + ( "encoding", bpo::value()-> default_value("win1252"), "Character encoding used in OpenMW game messages:\n" "\n\twin1250 - Central and Eastern European such as Polish, Czech, Slovak, Hungarian, Slovene, Bosnian, Croatian, Serbian (Latin script), Romanian and Albanian languages\n" "\n\twin1251 - Cyrillic alphabet such as Russian, Bulgarian, Serbian Cyrillic and other languages\n" "\n\twin1252 - Western European (Latin) alphabet, used by default") - ("report-focus", boost::program_options::value()->implicit_value(true) + ("report-focus", bpo::value()->implicit_value(true) ->default_value(false), "write name of focussed object to cout") + + ("fallback", bpo::value()->default_value(FallbackMap(), "") + ->multitoken()->composing(), "fallback values") + ; bpo::parsed_options valid_opts = bpo::command_line_parser(argc, argv) @@ -225,13 +261,13 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat engine.setNewGame(variables["new-game"].as()); // other settings - engine.showFPS(variables["fps"].as()); engine.setDebugMode(variables["debug"].as()); engine.setSoundUsage(!variables["nosound"].as()); engine.setScriptsVerbosity(variables["script-verbose"].as()); engine.setCompileAll(variables["script-all"].as()); engine.setReportFocus(variables["report-focus"].as()); engine.setAnimationVerbose(variables["anim-verbose"].as()); + engine.setFallbackValues(variables["fallback"].as().mMap); return true; } diff --git a/apps/openmw/mwclass/apparatus.cpp b/apps/openmw/mwclass/apparatus.cpp index e95fb572f..90db40b5a 100644 --- a/apps/openmw/mwclass/apparatus.cpp +++ b/apps/openmw/mwclass/apparatus.cpp @@ -56,7 +56,7 @@ namespace MWClass boost::shared_ptr Apparatus::activate (const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const { - environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, false, true); + environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWSound::Play_NoTrack); return boost::shared_ptr ( new MWWorld::ActionTake (ptr)); @@ -70,6 +70,14 @@ namespace MWClass return ref->base->script; } + int Apparatus::getValue (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return ref->base->data.value; + } + void Apparatus::registerSelf() { boost::shared_ptr instance (new Apparatus); diff --git a/apps/openmw/mwclass/apparatus.hpp b/apps/openmw/mwclass/apparatus.hpp index c0849e1fe..861610f6c 100644 --- a/apps/openmw/mwclass/apparatus.hpp +++ b/apps/openmw/mwclass/apparatus.hpp @@ -25,6 +25,9 @@ namespace MWClass virtual std::string getScript (const MWWorld::Ptr& ptr) const; ///< Return name of the script attached to ptr + virtual int getValue (const MWWorld::Ptr& ptr) const; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. + static void registerSelf(); virtual std::string getUpSoundId (const MWWorld::Ptr& ptr) const; diff --git a/apps/openmw/mwclass/armor.cpp b/apps/openmw/mwclass/armor.cpp index e1c2734f0..8e1f81136 100644 --- a/apps/openmw/mwclass/armor.cpp +++ b/apps/openmw/mwclass/armor.cpp @@ -60,7 +60,7 @@ namespace MWClass boost::shared_ptr Armor::activate (const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const { - environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, false, true); + environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, MWSound::Play_NoTrack); return boost::shared_ptr ( new MWWorld::ActionTake (ptr)); @@ -160,6 +160,14 @@ namespace MWClass return ESM::Skill::HeavyArmor; } + int Armor::getValue (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return ref->base->data.value; + } + void Armor::registerSelf() { boost::shared_ptr instance (new Armor); diff --git a/apps/openmw/mwclass/armor.hpp b/apps/openmw/mwclass/armor.hpp index 2b66ff828..de5ca3983 100644 --- a/apps/openmw/mwclass/armor.hpp +++ b/apps/openmw/mwclass/armor.hpp @@ -40,6 +40,9 @@ namespace MWClass /// Return the index of the skill this item corresponds to when equiopped or -1, if there is /// no such skill. + virtual int getValue (const MWWorld::Ptr& ptr) const; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. + static void registerSelf(); virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; diff --git a/apps/openmw/mwclass/book.cpp b/apps/openmw/mwclass/book.cpp index 0a81ebafb..9069d9476 100644 --- a/apps/openmw/mwclass/book.cpp +++ b/apps/openmw/mwclass/book.cpp @@ -58,7 +58,7 @@ namespace MWClass { // TODO implement reading - environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, false, true); + environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, MWSound::Play_NoTrack); return boost::shared_ptr ( new MWWorld::ActionTake (ptr)); @@ -72,6 +72,14 @@ namespace MWClass return ref->base->script; } + int Book::getValue (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return ref->base->data.value; + } + void Book::registerSelf() { boost::shared_ptr instance (new Book); diff --git a/apps/openmw/mwclass/book.hpp b/apps/openmw/mwclass/book.hpp index ccbbfb4b2..4738187cd 100644 --- a/apps/openmw/mwclass/book.hpp +++ b/apps/openmw/mwclass/book.hpp @@ -25,6 +25,9 @@ namespace MWClass virtual std::string getScript (const MWWorld::Ptr& ptr) const; ///< Return name of the script attached to ptr + virtual int getValue (const MWWorld::Ptr& ptr) const; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. + static void registerSelf(); virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; diff --git a/apps/openmw/mwclass/clothing.cpp b/apps/openmw/mwclass/clothing.cpp index 4fe19ada4..1fbc11c63 100644 --- a/apps/openmw/mwclass/clothing.cpp +++ b/apps/openmw/mwclass/clothing.cpp @@ -57,7 +57,7 @@ namespace MWClass boost::shared_ptr Clothing::activate (const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const { - environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, false, true); + environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, MWSound::Play_NoTrack); return boost::shared_ptr ( new MWWorld::ActionTake (ptr)); @@ -123,6 +123,14 @@ namespace MWClass return -1; } + int Clothing::getValue (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return ref->base->data.value; + } + void Clothing::registerSelf() { boost::shared_ptr instance (new Clothing); diff --git a/apps/openmw/mwclass/clothing.hpp b/apps/openmw/mwclass/clothing.hpp index 171b06246..97e09012d 100644 --- a/apps/openmw/mwclass/clothing.hpp +++ b/apps/openmw/mwclass/clothing.hpp @@ -34,6 +34,9 @@ namespace MWClass /// Return the index of the skill this item corresponds to when equiopped or -1, if there is /// no such skill. + virtual int getValue (const MWWorld::Ptr& ptr) const; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. + static void registerSelf(); virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; diff --git a/apps/openmw/mwclass/container.cpp b/apps/openmw/mwclass/container.cpp index c58a25c03..29b3331ba 100644 --- a/apps/openmw/mwclass/container.cpp +++ b/apps/openmw/mwclass/container.cpp @@ -85,7 +85,7 @@ namespace MWClass { // TODO check for key std::cout << "Locked container" << std::endl; - environment.mSoundManager->playSound3D (ptr, lockedSound, 1.0, 1.0, false); + environment.mSoundManager->playSound3D (ptr, lockedSound, 1.0, 1.0); return boost::shared_ptr (new MWWorld::NullAction); } else @@ -100,7 +100,7 @@ namespace MWClass { // Trap activation goes here std::cout << "Activated trap: " << ptr.getCellRef().trap << std::endl; - environment.mSoundManager->playSound3D (ptr, trapActivationSound, 1.0, 1.0, false); + environment.mSoundManager->playSound3D (ptr, trapActivationSound, 1.0, 1.0); ptr.getCellRef().trap = ""; return boost::shared_ptr (new MWWorld::NullAction); } diff --git a/apps/openmw/mwclass/door.cpp b/apps/openmw/mwclass/door.cpp index 5654dff69..9d6c6a78d 100644 --- a/apps/openmw/mwclass/door.cpp +++ b/apps/openmw/mwclass/door.cpp @@ -73,7 +73,7 @@ namespace MWClass // TODO check for key // TODO report failure to player (message, sound?). Look up behaviour of original MW. std::cout << "Locked!" << std::endl; - environment.mSoundManager->playSound3D (ptr, lockedSound, 1.0, 1.0, false); + environment.mSoundManager->playSound3D (ptr, lockedSound, 1.0, 1.0); return boost::shared_ptr (new MWWorld::NullAction); } @@ -81,7 +81,7 @@ namespace MWClass { // Trap activation std::cout << "Activated trap: " << ptr.getCellRef().trap << std::endl; - environment.mSoundManager->playSound3D(ptr, trapActivationSound, 1.0, 1.0, false); + environment.mSoundManager->playSound3D(ptr, trapActivationSound, 1.0, 1.0); ptr.getCellRef().trap = ""; return boost::shared_ptr (new MWWorld::NullAction); } @@ -110,7 +110,7 @@ namespace MWClass // TODO return action for rotating the door // This is a little pointless, but helps with testing - environment.mSoundManager->playSound3D (ptr, openSound, 1.0, 1.0, false); + environment.mSoundManager->playSound3D (ptr, openSound, 1.0, 1.0); return boost::shared_ptr (new MWWorld::NullAction); } } diff --git a/apps/openmw/mwclass/ingredient.cpp b/apps/openmw/mwclass/ingredient.cpp index 1a7edf632..9707e79a8 100644 --- a/apps/openmw/mwclass/ingredient.cpp +++ b/apps/openmw/mwclass/ingredient.cpp @@ -54,7 +54,7 @@ namespace MWClass boost::shared_ptr Ingredient::activate (const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const { - environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, false, true); + environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, MWSound::Play_NoTrack); return boost::shared_ptr ( new MWWorld::ActionTake (ptr)); @@ -68,6 +68,14 @@ namespace MWClass return ref->base->script; } + int Ingredient::getValue (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return ref->base->data.value; + } + void Ingredient::registerSelf() { boost::shared_ptr instance (new Ingredient); diff --git a/apps/openmw/mwclass/ingredient.hpp b/apps/openmw/mwclass/ingredient.hpp index 9463dcf8d..2d7717672 100644 --- a/apps/openmw/mwclass/ingredient.hpp +++ b/apps/openmw/mwclass/ingredient.hpp @@ -25,6 +25,9 @@ namespace MWClass virtual std::string getScript (const MWWorld::Ptr& ptr) const; ///< Return name of the script attached to ptr + virtual int getValue (const MWWorld::Ptr& ptr) const; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. + static void registerSelf(); virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; diff --git a/apps/openmw/mwclass/light.cpp b/apps/openmw/mwclass/light.cpp index e2e63a89b..f67dd4cf0 100644 --- a/apps/openmw/mwclass/light.cpp +++ b/apps/openmw/mwclass/light.cpp @@ -59,7 +59,7 @@ namespace MWClass if (!ref->base->sound.empty()) { - environment.mSoundManager->playSound3D (ptr, ref->base->sound, 1.0, 1.0, true); + environment.mSoundManager->playSound3D (ptr, ref->base->sound, 1.0, 1.0, MWSound::Play_Loop); } } @@ -83,7 +83,7 @@ namespace MWClass if (!(ref->base->data.flags & ESM::Light::Carry)) return boost::shared_ptr (new MWWorld::NullAction); - environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, false, true); + environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, MWSound::Play_NoTrack); return boost::shared_ptr ( new MWWorld::ActionTake (ptr)); @@ -110,6 +110,14 @@ namespace MWClass return std::make_pair (slots, false); } + int Light::getValue (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return ref->base->data.value; + } + void Light::registerSelf() { boost::shared_ptr instance (new Light); diff --git a/apps/openmw/mwclass/light.hpp b/apps/openmw/mwclass/light.hpp index 46a4d60ba..bde252c28 100644 --- a/apps/openmw/mwclass/light.hpp +++ b/apps/openmw/mwclass/light.hpp @@ -34,6 +34,9 @@ namespace MWClass ///< \return first: Return IDs of the slot this object can be equipped in; second: can object /// stay stacked when equipped? + virtual int getValue (const MWWorld::Ptr& ptr) const; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. + static void registerSelf(); virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; diff --git a/apps/openmw/mwclass/lockpick.cpp b/apps/openmw/mwclass/lockpick.cpp index 3dda2f4af..76bc3948f 100644 --- a/apps/openmw/mwclass/lockpick.cpp +++ b/apps/openmw/mwclass/lockpick.cpp @@ -58,7 +58,7 @@ namespace MWClass boost::shared_ptr Lockpick::activate (const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const { - environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, false, true); + environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, MWSound::Play_NoTrack); return boost::shared_ptr ( new MWWorld::ActionTake (ptr)); @@ -81,6 +81,14 @@ namespace MWClass return std::make_pair (slots, false); } + int Lockpick::getValue (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return ref->base->data.value; + } + void Lockpick::registerSelf() { boost::shared_ptr instance (new Lockpick); diff --git a/apps/openmw/mwclass/lockpick.hpp b/apps/openmw/mwclass/lockpick.hpp index 0c9189c54..1b56234af 100644 --- a/apps/openmw/mwclass/lockpick.hpp +++ b/apps/openmw/mwclass/lockpick.hpp @@ -29,6 +29,9 @@ namespace MWClass ///< \return first: Return IDs of the slot this object can be equipped in; second: can object /// stay stacked when equipped? + virtual int getValue (const MWWorld::Ptr& ptr) const; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. + static void registerSelf(); virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; diff --git a/apps/openmw/mwclass/misc.cpp b/apps/openmw/mwclass/misc.cpp index 864fc1e38..84099caaa 100644 --- a/apps/openmw/mwclass/misc.cpp +++ b/apps/openmw/mwclass/misc.cpp @@ -56,7 +56,7 @@ namespace MWClass boost::shared_ptr Miscellaneous::activate (const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const { - environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, false, true); + environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, MWSound::Play_NoTrack); return boost::shared_ptr ( new MWWorld::ActionTake (ptr)); @@ -70,6 +70,14 @@ namespace MWClass return ref->base->script; } + int Miscellaneous::getValue (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return ref->base->data.value; + } + void Miscellaneous::registerSelf() { boost::shared_ptr instance (new Miscellaneous); diff --git a/apps/openmw/mwclass/misc.hpp b/apps/openmw/mwclass/misc.hpp index b07964f99..fc002280c 100644 --- a/apps/openmw/mwclass/misc.hpp +++ b/apps/openmw/mwclass/misc.hpp @@ -25,6 +25,9 @@ namespace MWClass virtual std::string getScript (const MWWorld::Ptr& ptr) const; ///< Return name of the script attached to ptr + virtual int getValue (const MWWorld::Ptr& ptr) const; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. + static void registerSelf(); virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; diff --git a/apps/openmw/mwclass/potion.cpp b/apps/openmw/mwclass/potion.cpp index 4ab374590..642211df3 100644 --- a/apps/openmw/mwclass/potion.cpp +++ b/apps/openmw/mwclass/potion.cpp @@ -56,7 +56,7 @@ namespace MWClass boost::shared_ptr Potion::activate (const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const { - environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, false, true); + environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, MWSound::Play_NoTrack); return boost::shared_ptr ( new MWWorld::ActionTake (ptr)); @@ -70,6 +70,14 @@ namespace MWClass return ref->base->script; } + int Potion::getValue (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return ref->base->data.value; + } + void Potion::registerSelf() { boost::shared_ptr instance (new Potion); diff --git a/apps/openmw/mwclass/potion.hpp b/apps/openmw/mwclass/potion.hpp index be9e713fb..7d3017937 100644 --- a/apps/openmw/mwclass/potion.hpp +++ b/apps/openmw/mwclass/potion.hpp @@ -25,6 +25,9 @@ namespace MWClass virtual std::string getScript (const MWWorld::Ptr& ptr) const; ///< Return name of the script attached to ptr + virtual int getValue (const MWWorld::Ptr& ptr) const; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. + static void registerSelf(); virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; diff --git a/apps/openmw/mwclass/probe.cpp b/apps/openmw/mwclass/probe.cpp index 4b4d79a73..923c29ee6 100644 --- a/apps/openmw/mwclass/probe.cpp +++ b/apps/openmw/mwclass/probe.cpp @@ -57,7 +57,7 @@ namespace MWClass boost::shared_ptr Probe::activate (const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const { - environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, false, true); + environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, MWSound::Play_NoTrack); return boost::shared_ptr ( new MWWorld::ActionTake (ptr)); @@ -80,6 +80,14 @@ namespace MWClass return std::make_pair (slots, false); } + int Probe::getValue (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return ref->base->data.value; + } + void Probe::registerSelf() { boost::shared_ptr instance (new Probe); diff --git a/apps/openmw/mwclass/probe.hpp b/apps/openmw/mwclass/probe.hpp index 1507d65aa..232b52364 100644 --- a/apps/openmw/mwclass/probe.hpp +++ b/apps/openmw/mwclass/probe.hpp @@ -29,6 +29,9 @@ namespace MWClass ///< \return first: Return IDs of the slot this object can be equipped in; second: can object /// stay stacked when equipped? + virtual int getValue (const MWWorld::Ptr& ptr) const; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. + static void registerSelf(); virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; diff --git a/apps/openmw/mwclass/repair.cpp b/apps/openmw/mwclass/repair.cpp index 758bf4079..d6433f5df 100644 --- a/apps/openmw/mwclass/repair.cpp +++ b/apps/openmw/mwclass/repair.cpp @@ -56,7 +56,7 @@ namespace MWClass boost::shared_ptr Repair::activate (const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const { - environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, false, true); + environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, MWSound::Play_NoTrack); return boost::shared_ptr ( new MWWorld::ActionTake (ptr)); @@ -70,6 +70,14 @@ namespace MWClass return ref->base->script; } + int Repair::getValue (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return ref->base->data.value; + } + void Repair::registerSelf() { boost::shared_ptr instance (new Repair); diff --git a/apps/openmw/mwclass/repair.hpp b/apps/openmw/mwclass/repair.hpp index 17b606f4c..0a9d9c253 100644 --- a/apps/openmw/mwclass/repair.hpp +++ b/apps/openmw/mwclass/repair.hpp @@ -25,6 +25,9 @@ namespace MWClass virtual std::string getScript (const MWWorld::Ptr& ptr) const; ///< Return name of the script attached to ptr + virtual int getValue (const MWWorld::Ptr& ptr) const; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. + static void registerSelf(); virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; diff --git a/apps/openmw/mwclass/weapon.cpp b/apps/openmw/mwclass/weapon.cpp index 20db0cf38..7790e6a80 100644 --- a/apps/openmw/mwclass/weapon.cpp +++ b/apps/openmw/mwclass/weapon.cpp @@ -57,7 +57,7 @@ namespace MWClass boost::shared_ptr Weapon::activate (const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const { - environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, false, true); + environment.mSoundManager->playSound3D (ptr, getUpSoundId(ptr, environment), 1.0, 1.0, MWSound::Play_NoTrack); return boost::shared_ptr ( new MWWorld::ActionTake (ptr)); @@ -139,6 +139,14 @@ namespace MWClass return -1; } + int Weapon::getValue (const MWWorld::Ptr& ptr) const + { + ESMS::LiveCellRef *ref = + ptr.get(); + + return ref->base->data.value; + } + void Weapon::registerSelf() { boost::shared_ptr instance (new Weapon); diff --git a/apps/openmw/mwclass/weapon.hpp b/apps/openmw/mwclass/weapon.hpp index f863c0bfe..505c45645 100644 --- a/apps/openmw/mwclass/weapon.hpp +++ b/apps/openmw/mwclass/weapon.hpp @@ -40,6 +40,9 @@ namespace MWClass /// Return the index of the skill this item corresponds to when equiopped or -1, if there is /// no such skill. + virtual int getValue (const MWWorld::Ptr& ptr) const; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. + static void registerSelf(); virtual std::string getUpSoundId (const MWWorld::Ptr& ptr, const MWWorld::Environment& environment) const; diff --git a/apps/openmw/mwdialogue/dialoguemanager.cpp b/apps/openmw/mwdialogue/dialoguemanager.cpp index dd57dfda0..b06605cc2 100644 --- a/apps/openmw/mwdialogue/dialoguemanager.cpp +++ b/apps/openmw/mwdialogue/dialoguemanager.cpp @@ -145,8 +145,6 @@ namespace MWDialogue bool DialogueManager::functionFilter(const MWWorld::Ptr& actor, const ESM::DialInfo& info,bool choice) { - bool isAChoice = false;//is there any choice in the filters? - bool isFunction = false; for (std::vector::const_iterator iter (info.selects.begin()); iter != info.selects.end(); ++iter) { @@ -154,7 +152,6 @@ namespace MWDialogue char type = select.selectRule[1]; if(type == '1') { - isFunction = true; char comp = select.selectRule[4]; std::string name = select.selectRule.substr (5); std::string function = select.selectRule.substr(2,2); @@ -193,7 +190,7 @@ namespace MWDialogue break; case 50://choice - isAChoice = true; + if(choice) { if(!selectCompare(comp,mChoice,select.i)) return false; @@ -516,7 +513,6 @@ namespace MWDialogue return false; // TODO check DATAstruct - for (std::vector::const_iterator iter (info.selects.begin()); iter != info.selects.end(); ++iter) if (!isMatching (actor, *iter)) @@ -532,6 +528,13 @@ namespace MWDialogue mChoice = -1; mIsInChoice = false; mCompilerContext.setExtensions (&extensions); + mDialogueMap.clear(); + actorKnownTopics.clear(); + ESMS::RecListT::MapType dialogueList = mEnvironment.mWorld->getStore().dialogs.list; + for(ESMS::RecListT::MapType::iterator it = dialogueList.begin(); it!=dialogueList.end();it++) + { + mDialogueMap[it->first] = it->second; + } } void DialogueManager::addTopic(std::string topic) @@ -567,13 +570,7 @@ namespace MWDialogue mActor = actor; - mDialogueMap.clear(); actorKnownTopics.clear(); - ESMS::RecListT::MapType dialogueList = mEnvironment.mWorld->getStore().dialogs.list; - for(ESMS::RecListT::MapType::iterator it = dialogueList.begin(); it!=dialogueList.end();it++) - { - mDialogueMap[it->first] = it->second; - } //initialise the GUI mEnvironment.mInputManager->setGuiMode(MWGui::GM_Dialogue); @@ -586,6 +583,7 @@ namespace MWDialogue //greeting bool greetingFound = false; //ESMS::RecListT::MapType dialogueList = mEnvironment.mWorld->getStore().dialogs.list; + ESMS::RecListT::MapType dialogueList = mEnvironment.mWorld->getStore().dialogs.list; for(ESMS::RecListT::MapType::iterator it = dialogueList.begin(); it!=dialogueList.end();it++) { ESM::Dialogue ndialogue = it->second; @@ -680,7 +678,8 @@ namespace MWDialogue void DialogueManager::updateTopics() { std::list keywordList; - + int choice = mChoice; + mChoice = -1; actorKnownTopics.clear(); MWGui::DialogueWindow* win = mEnvironment.mWindowManager->getDialogueWindow(); ESMS::RecListT::MapType dialogueList = mEnvironment.mWorld->getStore().dialogs.list; @@ -692,7 +691,7 @@ namespace MWDialogue for (std::vector::const_iterator iter (it->second.mInfo.begin()); iter!=it->second.mInfo.end(); ++iter) { - if (isMatching (mActor, *iter) && functionFilter(mActor,*iter,false)) + if (isMatching (mActor, *iter) && functionFilter(mActor,*iter,true)) { actorKnownTopics.push_back(it->first); //does the player know the topic? @@ -706,6 +705,7 @@ namespace MWDialogue } } win->setKeywords(keywordList); + mChoice = choice; } void DialogueManager::keywordSelected(std::string keyword) @@ -715,10 +715,9 @@ namespace MWDialogue if(mDialogueMap.find(keyword) != mDialogueMap.end()) { ESM::Dialogue ndialogue = mDialogueMap[keyword]; - std::vector::const_iterator iter; if(ndialogue.type == ESM::Dialogue::Topic) { - for (iter = ndialogue.mInfo.begin(); + for (std::vector::const_iterator iter = ndialogue.mInfo.begin(); iter!=ndialogue.mInfo.end(); ++iter) { if (isMatching (mActor, *iter) && functionFilter(mActor,*iter,true)) @@ -742,6 +741,7 @@ namespace MWDialogue } } } + updateTopics(); } diff --git a/apps/openmw/mwgui/birth.cpp b/apps/openmw/mwgui/birth.cpp index 93dde9f1b..e9c15fab4 100644 --- a/apps/openmw/mwgui/birth.cpp +++ b/apps/openmw/mwgui/birth.cpp @@ -21,18 +21,18 @@ BirthDialog::BirthDialog(WindowManager& parWindowManager) getWidget(birthList, "BirthsignList"); birthList->setScrollVisible(true); - birthList->eventListSelectAccept = MyGUI::newDelegate(this, &BirthDialog::onSelectBirth); - birthList->eventListMouseItemActivate = MyGUI::newDelegate(this, &BirthDialog::onSelectBirth); - birthList->eventListChangePosition = MyGUI::newDelegate(this, &BirthDialog::onSelectBirth); + birthList->eventListSelectAccept += MyGUI::newDelegate(this, &BirthDialog::onSelectBirth); + birthList->eventListMouseItemActivate += MyGUI::newDelegate(this, &BirthDialog::onSelectBirth); + birthList->eventListChangePosition += MyGUI::newDelegate(this, &BirthDialog::onSelectBirth); // TODO: These buttons should be managed by a Dialog class MyGUI::ButtonPtr backButton; getWidget(backButton, "BackButton"); - backButton->eventMouseButtonClick = MyGUI::newDelegate(this, &BirthDialog::onBackClicked); + backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BirthDialog::onBackClicked); MyGUI::ButtonPtr okButton; getWidget(okButton, "OKButton"); - okButton->eventMouseButtonClick = MyGUI::newDelegate(this, &BirthDialog::onOkClicked); + okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BirthDialog::onOkClicked); updateBirths(); updateSpells(); @@ -100,7 +100,7 @@ void BirthDialog::onBackClicked(MyGUI::Widget* _sender) eventBack(); } -void BirthDialog::onSelectBirth(MyGUI::List* _sender, size_t _index) +void BirthDialog::onSelectBirth(MyGUI::ListBox* _sender, size_t _index) { if (_index == MyGUI::ITEM_NONE) return; @@ -188,7 +188,7 @@ void BirthDialog::updateSpells() { if (!categories[category].spells.empty()) { - MyGUI::StaticTextPtr label = spellArea->createWidget("SandBrightText", coord, MyGUI::Align::Default, std::string("Label")); + MyGUI::TextBox* label = spellArea->createWidget("SandBrightText", coord, MyGUI::Align::Default, std::string("Label")); label->setCaption(mWindowManager.getGameSettingString(categories[category].label, "")); spellItems.push_back(label); coord.top += lineHeight; diff --git a/apps/openmw/mwgui/birth.hpp b/apps/openmw/mwgui/birth.hpp index a55a774a5..b5f7db774 100644 --- a/apps/openmw/mwgui/birth.hpp +++ b/apps/openmw/mwgui/birth.hpp @@ -32,7 +32,7 @@ namespace MWGui void open(); // Events - typedef delegates::CDelegate0 EventHandle_Void; + typedef delegates::CMultiDelegate0 EventHandle_Void; /** Event : Back button clicked.\n signature : void method()\n @@ -40,7 +40,7 @@ namespace MWGui EventHandle_Void eventBack; protected: - void onSelectBirth(MyGUI::List* _sender, size_t _index); + void onSelectBirth(MyGUI::ListBox* _sender, size_t _index); void onOkClicked(MyGUI::Widget* _sender); void onBackClicked(MyGUI::Widget* _sender); @@ -49,9 +49,9 @@ namespace MWGui void updateBirths(); void updateSpells(); - MyGUI::ListPtr birthList; + MyGUI::ListBox* birthList; MyGUI::WidgetPtr spellArea; - MyGUI::StaticImagePtr birthImage; + MyGUI::ImageBox* birthImage; std::vector spellItems; std::string currentBirthId; diff --git a/apps/openmw/mwgui/charactercreation.cpp b/apps/openmw/mwgui/charactercreation.cpp index 1cb0593e7..ce5e744cc 100644 --- a/apps/openmw/mwgui/charactercreation.cpp +++ b/apps/openmw/mwgui/charactercreation.cpp @@ -121,7 +121,7 @@ void CharacterCreation::spawnDialog(const char id) mNameDialog->setTextLabel(mWM->getGameSettingString("sName", "Name")); mNameDialog->setTextInput(mPlayerName); mNameDialog->setNextButtonShow(mCreationStage >= CSE_NameChosen); - mNameDialog->eventDone = MyGUI::newDelegate(this, &CharacterCreation::onNameDialogDone); + mNameDialog->eventDone += MyGUI::newDelegate(this, &CharacterCreation::onNameDialogDone); mNameDialog->open(); break; @@ -131,8 +131,8 @@ void CharacterCreation::spawnDialog(const char id) mRaceDialog = new RaceDialog(*mWM); mRaceDialog->setNextButtonShow(mCreationStage >= CSE_RaceChosen); mRaceDialog->setRaceId(mPlayerRaceId); - mRaceDialog->eventDone = MyGUI::newDelegate(this, &CharacterCreation::onRaceDialogDone); - mRaceDialog->eventBack = MyGUI::newDelegate(this, &CharacterCreation::onRaceDialogBack); + mRaceDialog->eventDone += MyGUI::newDelegate(this, &CharacterCreation::onRaceDialogDone); + mRaceDialog->eventBack += MyGUI::newDelegate(this, &CharacterCreation::onRaceDialogBack); mRaceDialog->open(); break; @@ -140,7 +140,7 @@ void CharacterCreation::spawnDialog(const char id) if (mClassChoiceDialog) mWM->removeDialog(mClassChoiceDialog); mClassChoiceDialog = new ClassChoiceDialog(*mWM); - mClassChoiceDialog->eventButtonSelected = MyGUI::newDelegate(this, &CharacterCreation::onClassChoice); + mClassChoiceDialog->eventButtonSelected += MyGUI::newDelegate(this, &CharacterCreation::onClassChoice); mClassChoiceDialog->open(); break; @@ -150,8 +150,8 @@ void CharacterCreation::spawnDialog(const char id) mPickClassDialog = new PickClassDialog(*mWM); mPickClassDialog->setNextButtonShow(mCreationStage >= CSE_ClassChosen); mPickClassDialog->setClassId(mPlayerClass.name); - mPickClassDialog->eventDone = MyGUI::newDelegate(this, &CharacterCreation::onPickClassDialogDone); - mPickClassDialog->eventBack = MyGUI::newDelegate(this, &CharacterCreation::onPickClassDialogBack); + mPickClassDialog->eventDone += MyGUI::newDelegate(this, &CharacterCreation::onPickClassDialogDone); + mPickClassDialog->eventBack += MyGUI::newDelegate(this, &CharacterCreation::onPickClassDialogBack); mPickClassDialog->open(); break; @@ -161,8 +161,8 @@ void CharacterCreation::spawnDialog(const char id) mBirthSignDialog = new BirthDialog(*mWM); mBirthSignDialog->setNextButtonShow(mCreationStage >= CSE_BirthSignChosen); mBirthSignDialog->setBirthId(mPlayerBirthSignId); - mBirthSignDialog->eventDone = MyGUI::newDelegate(this, &CharacterCreation::onBirthSignDialogDone); - mBirthSignDialog->eventBack = MyGUI::newDelegate(this, &CharacterCreation::onBirthSignDialogBack); + mBirthSignDialog->eventDone += MyGUI::newDelegate(this, &CharacterCreation::onBirthSignDialogDone); + mBirthSignDialog->eventBack += MyGUI::newDelegate(this, &CharacterCreation::onBirthSignDialogBack); mBirthSignDialog->open(); break; @@ -170,8 +170,8 @@ void CharacterCreation::spawnDialog(const char id) if (mCreateClassDialog) mWM->removeDialog(mCreateClassDialog); mCreateClassDialog = new CreateClassDialog(*mWM); - mCreateClassDialog->eventDone = MyGUI::newDelegate(this, &CharacterCreation::onCreateClassDialogDone); - mCreateClassDialog->eventBack = MyGUI::newDelegate(this, &CharacterCreation::onCreateClassDialogBack); + mCreateClassDialog->eventDone += MyGUI::newDelegate(this, &CharacterCreation::onCreateClassDialogDone); + mCreateClassDialog->eventBack += MyGUI::newDelegate(this, &CharacterCreation::onCreateClassDialogBack); mCreateClassDialog->open(); break; case GM_ClassGenerate: @@ -212,9 +212,9 @@ void CharacterCreation::spawnDialog(const char id) mReviewDialog->configureSkills(mPlayerMajorSkills, mPlayerMinorSkills); } - mReviewDialog->eventDone = MyGUI::newDelegate(this, &CharacterCreation::onReviewDialogDone); - mReviewDialog->eventBack = MyGUI::newDelegate(this, &CharacterCreation::onReviewDialogBack); - mReviewDialog->eventActivateDialog = MyGUI::newDelegate(this, &CharacterCreation::onReviewActivateDialog); + mReviewDialog->eventDone += MyGUI::newDelegate(this, &CharacterCreation::onReviewDialogDone); + mReviewDialog->eventBack += MyGUI::newDelegate(this, &CharacterCreation::onReviewDialogBack); + mReviewDialog->eventActivateDialog += MyGUI::newDelegate(this, &CharacterCreation::onReviewActivateDialog); mReviewDialog->open(); break; } @@ -559,8 +559,8 @@ void CharacterCreation::showClassQuestionDialog() mWM->removeDialog(mGenerateClassResultDialog); mGenerateClassResultDialog = new GenerateClassResultDialog(*mWM); mGenerateClassResultDialog->setClassId(mGenerateClass); - mGenerateClassResultDialog->eventBack = MyGUI::newDelegate(this, &CharacterCreation::onGenerateClassBack); - mGenerateClassResultDialog->eventDone = MyGUI::newDelegate(this, &CharacterCreation::onGenerateClassDone); + mGenerateClassResultDialog->eventBack += MyGUI::newDelegate(this, &CharacterCreation::onGenerateClassBack); + mGenerateClassResultDialog->eventDone += MyGUI::newDelegate(this, &CharacterCreation::onGenerateClassDone); mGenerateClassResultDialog->open(); return; } @@ -581,7 +581,7 @@ void CharacterCreation::showClassQuestionDialog() buttons.push_back(sGenerateClassSteps[mGenerateClassStep].mButtons[1]); buttons.push_back(sGenerateClassSteps[mGenerateClassStep].mButtons[2]); mGenerateClassQuestionDialog->setButtons(buttons); - mGenerateClassQuestionDialog->eventButtonSelected = MyGUI::newDelegate(this, &CharacterCreation::onClassQuestionChosen); + mGenerateClassQuestionDialog->eventButtonSelected += MyGUI::newDelegate(this, &CharacterCreation::onClassQuestionChosen); mGenerateClassQuestionDialog->open(); } diff --git a/apps/openmw/mwgui/class.cpp b/apps/openmw/mwgui/class.cpp index ad94f30b1..75e534b42 100644 --- a/apps/openmw/mwgui/class.cpp +++ b/apps/openmw/mwgui/class.cpp @@ -29,11 +29,11 @@ GenerateClassResultDialog::GenerateClassResultDialog(WindowManager& parWindowMan // TODO: These buttons should be managed by a Dialog class MyGUI::ButtonPtr backButton; getWidget(backButton, "BackButton"); - backButton->eventMouseButtonClick = MyGUI::newDelegate(this, &GenerateClassResultDialog::onBackClicked); + backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &GenerateClassResultDialog::onBackClicked); MyGUI::ButtonPtr okButton; getWidget(okButton, "OKButton"); - okButton->eventMouseButtonClick = MyGUI::newDelegate(this, &GenerateClassResultDialog::onOkClicked); + okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &GenerateClassResultDialog::onOkClicked); } void GenerateClassResultDialog::open() @@ -96,20 +96,20 @@ PickClassDialog::PickClassDialog(WindowManager& parWindowManager) getWidget(classList, "ClassList"); classList->setScrollVisible(true); - classList->eventListSelectAccept = MyGUI::newDelegate(this, &PickClassDialog::onSelectClass); - classList->eventListMouseItemActivate = MyGUI::newDelegate(this, &PickClassDialog::onSelectClass); - classList->eventListChangePosition = MyGUI::newDelegate(this, &PickClassDialog::onSelectClass); + classList->eventListSelectAccept += MyGUI::newDelegate(this, &PickClassDialog::onSelectClass); + classList->eventListMouseItemActivate += MyGUI::newDelegate(this, &PickClassDialog::onSelectClass); + classList->eventListChangePosition += MyGUI::newDelegate(this, &PickClassDialog::onSelectClass); getWidget(classImage, "ClassImage"); // TODO: These buttons should be managed by a Dialog class MyGUI::ButtonPtr backButton; getWidget(backButton, "BackButton"); - backButton->eventMouseButtonClick = MyGUI::newDelegate(this, &PickClassDialog::onBackClicked); + backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &PickClassDialog::onBackClicked); MyGUI::ButtonPtr okButton; getWidget(okButton, "OKButton"); - okButton->eventMouseButtonClick = MyGUI::newDelegate(this, &PickClassDialog::onOkClicked); + okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &PickClassDialog::onOkClicked); updateClasses(); updateStats(); @@ -177,7 +177,7 @@ void PickClassDialog::onBackClicked(MyGUI::Widget* _sender) eventBack(); } -void PickClassDialog::onSelectClass(MyGUI::List* _sender, size_t _index) +void PickClassDialog::onSelectClass(MyGUI::ListBox* _sender, size_t _index) { if (_index == MyGUI::ITEM_NONE) return; @@ -248,7 +248,7 @@ void PickClassDialog::updateStats() /* InfoBoxDialog */ -void InfoBoxDialog::fitToText(MyGUI::StaticTextPtr widget) +void InfoBoxDialog::fitToText(MyGUI::TextBox* widget) { MyGUI::IntCoord inner = widget->getTextRegion(); MyGUI::IntCoord outer = widget->getCoord(); @@ -267,7 +267,7 @@ void InfoBoxDialog::layoutVertically(MyGUI::WidgetPtr widget, int margin) for (unsigned i = 0; i < count; ++i) { MyGUI::WidgetPtr child = widget->getChildAt(i); - if (!child->isVisible()) + if (!child->getVisible()) continue; child->setPosition(child->getLeft(), pos); @@ -322,7 +322,7 @@ void InfoBoxDialog::setButtons(ButtonList &buttons) button->getSubWidgetText()->setWordWrap(true); button->setCaption(text); fitToText(button); - button->eventMouseButtonClick = MyGUI::newDelegate(this, &InfoBoxDialog::onButtonClicked); + button->eventMouseButtonClick += MyGUI::newDelegate(this, &InfoBoxDialog::onButtonClicked); coord.top += button->getHeight(); this->buttons.push_back(button); } @@ -389,15 +389,15 @@ CreateClassDialog::CreateClassDialog(WindowManager& parWindowManager) setText("SpecializationT", mWindowManager.getGameSettingString("sChooseClassMenu1", "Specialization")); getWidget(specializationName, "SpecializationName"); specializationName->setCaption(mWindowManager.getGameSettingString(ESM::Class::gmstSpecializationIds[ESM::Class::Combat], "")); - specializationName->eventMouseButtonClick = MyGUI::newDelegate(this, &CreateClassDialog::onSpecializationClicked); + specializationName->eventMouseButtonClick += MyGUI::newDelegate(this, &CreateClassDialog::onSpecializationClicked); setText("FavoriteAttributesT", mWindowManager.getGameSettingString("sChooseClassMenu2", "Favorite Attributes:")); getWidget(favoriteAttribute0, "FavoriteAttribute0"); getWidget(favoriteAttribute1, "FavoriteAttribute1"); favoriteAttribute0->setWindowManager(&mWindowManager); favoriteAttribute1->setWindowManager(&mWindowManager); - favoriteAttribute0->eventClicked = MyGUI::newDelegate(this, &CreateClassDialog::onAttributeClicked); - favoriteAttribute1->eventClicked = MyGUI::newDelegate(this, &CreateClassDialog::onAttributeClicked); + favoriteAttribute0->eventClicked += MyGUI::newDelegate(this, &CreateClassDialog::onAttributeClicked); + favoriteAttribute1->eventClicked += MyGUI::newDelegate(this, &CreateClassDialog::onAttributeClicked); setText("MajorSkillT", mWindowManager.getGameSettingString("sSkillClassMajor", "")); setText("MinorSkillT", mWindowManager.getGameSettingString("sSkillClassMinor", "")); @@ -414,7 +414,7 @@ CreateClassDialog::CreateClassDialog(WindowManager& parWindowManager) for (std::vector::const_iterator it = skills.begin(); it != end; ++it) { (*it)->setWindowManager(&mWindowManager); - (*it)->eventClicked = MyGUI::newDelegate(this, &CreateClassDialog::onSkillClicked); + (*it)->eventClicked += MyGUI::newDelegate(this, &CreateClassDialog::onSkillClicked); } setText("LabelT", mWindowManager.getGameSettingString("sName", "")); @@ -426,15 +426,15 @@ CreateClassDialog::CreateClassDialog(WindowManager& parWindowManager) // TODO: These buttons should be managed by a Dialog class MyGUI::ButtonPtr descriptionButton; getWidget(descriptionButton, "DescriptionButton"); - descriptionButton->eventMouseButtonClick = MyGUI::newDelegate(this, &CreateClassDialog::onDescriptionClicked); + descriptionButton->eventMouseButtonClick += MyGUI::newDelegate(this, &CreateClassDialog::onDescriptionClicked); MyGUI::ButtonPtr backButton; getWidget(backButton, "BackButton"); - backButton->eventMouseButtonClick = MyGUI::newDelegate(this, &CreateClassDialog::onBackClicked); + backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &CreateClassDialog::onBackClicked); MyGUI::ButtonPtr okButton; getWidget(okButton, "OKButton"); - okButton->eventMouseButtonClick = MyGUI::newDelegate(this, &CreateClassDialog::onOkClicked); + okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &CreateClassDialog::onOkClicked); // Set default skills, attributes @@ -560,8 +560,8 @@ void CreateClassDialog::onSpecializationClicked(MyGUI::WidgetPtr _sender) if (specDialog) delete specDialog; specDialog = new SelectSpecializationDialog(mWindowManager); - specDialog->eventCancel = MyGUI::newDelegate(this, &CreateClassDialog::onDialogCancel); - specDialog->eventItemSelected = MyGUI::newDelegate(this, &CreateClassDialog::onSpecializationSelected); + specDialog->eventCancel += MyGUI::newDelegate(this, &CreateClassDialog::onDialogCancel); + specDialog->eventItemSelected += MyGUI::newDelegate(this, &CreateClassDialog::onSpecializationSelected); specDialog->setVisible(true); } @@ -578,8 +578,8 @@ void CreateClassDialog::onAttributeClicked(Widgets::MWAttributePtr _sender) delete attribDialog; attribDialog = new SelectAttributeDialog(mWindowManager); attribDialog->setAffectedWidget(_sender); - attribDialog->eventCancel = MyGUI::newDelegate(this, &CreateClassDialog::onDialogCancel); - attribDialog->eventItemSelected = MyGUI::newDelegate(this, &CreateClassDialog::onAttributeSelected); + attribDialog->eventCancel += MyGUI::newDelegate(this, &CreateClassDialog::onDialogCancel); + attribDialog->eventItemSelected += MyGUI::newDelegate(this, &CreateClassDialog::onAttributeSelected); attribDialog->setVisible(true); } @@ -607,8 +607,8 @@ void CreateClassDialog::onSkillClicked(Widgets::MWSkillPtr _sender) delete skillDialog; skillDialog = new SelectSkillDialog(mWindowManager); skillDialog->setAffectedWidget(_sender); - skillDialog->eventCancel = MyGUI::newDelegate(this, &CreateClassDialog::onDialogCancel); - skillDialog->eventItemSelected = MyGUI::newDelegate(this, &CreateClassDialog::onSkillSelected); + skillDialog->eventCancel += MyGUI::newDelegate(this, &CreateClassDialog::onDialogCancel); + skillDialog->eventItemSelected += MyGUI::newDelegate(this, &CreateClassDialog::onSkillSelected); skillDialog->setVisible(true); } @@ -638,7 +638,7 @@ void CreateClassDialog::onDescriptionClicked(MyGUI::Widget* _sender) { descDialog = new DescriptionDialog(mWindowManager); descDialog->setTextInput(description); - descDialog->eventDone = MyGUI::newDelegate(this, &CreateClassDialog::onDescriptionEntered); + descDialog->eventDone += MyGUI::newDelegate(this, &CreateClassDialog::onDescriptionEntered); descDialog->setVisible(true); } @@ -672,18 +672,18 @@ SelectSpecializationDialog::SelectSpecializationDialog(WindowManager& parWindowM getWidget(specialization1, "Specialization1"); getWidget(specialization2, "Specialization2"); specialization0->setCaption(mWindowManager.getGameSettingString(ESM::Class::gmstSpecializationIds[ESM::Class::Combat], "")); - specialization0->eventMouseButtonClick = MyGUI::newDelegate(this, &SelectSpecializationDialog::onSpecializationClicked); + specialization0->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectSpecializationDialog::onSpecializationClicked); specialization1->setCaption(mWindowManager.getGameSettingString(ESM::Class::gmstSpecializationIds[ESM::Class::Magic], "")); - specialization1->eventMouseButtonClick = MyGUI::newDelegate(this, &SelectSpecializationDialog::onSpecializationClicked); + specialization1->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectSpecializationDialog::onSpecializationClicked); specialization2->setCaption(mWindowManager.getGameSettingString(ESM::Class::gmstSpecializationIds[ESM::Class::Stealth], "")); - specialization2->eventMouseButtonClick = MyGUI::newDelegate(this, &SelectSpecializationDialog::onSpecializationClicked); + 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(mWindowManager.getGameSettingString("sCancel", "")); - cancelButton->eventMouseButtonClick = MyGUI::newDelegate(this, &SelectSpecializationDialog::onCancelClicked); + cancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectSpecializationDialog::onCancelClicked); } // widget controls @@ -725,14 +725,14 @@ SelectAttributeDialog::SelectAttributeDialog(WindowManager& parWindowManager) getWidget(attribute, std::string("Attribute").append(1, theIndex)); attribute->setWindowManager(&parWindowManager); attribute->setAttributeId(ESM::Attribute::attributeIds[i]); - attribute->eventClicked = MyGUI::newDelegate(this, &SelectAttributeDialog::onAttributeClicked); + attribute->eventClicked += MyGUI::newDelegate(this, &SelectAttributeDialog::onAttributeClicked); } // TODO: These buttons should be managed by a Dialog class MyGUI::ButtonPtr cancelButton; getWidget(cancelButton, "CancelButton"); cancelButton->setCaption(mWindowManager.getGameSettingString("sCancel", "")); - cancelButton->eventMouseButtonClick = MyGUI::newDelegate(this, &SelectAttributeDialog::onCancelClicked); + cancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectAttributeDialog::onCancelClicked); } // widget controls @@ -813,7 +813,7 @@ SelectSkillDialog::SelectSkillDialog(WindowManager& parWindowManager) { 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); + skills[spec][i].widget->eventClicked += MyGUI::newDelegate(this, &SelectSkillDialog::onSkillClicked); } } @@ -821,7 +821,7 @@ SelectSkillDialog::SelectSkillDialog(WindowManager& parWindowManager) MyGUI::ButtonPtr cancelButton; getWidget(cancelButton, "CancelButton"); cancelButton->setCaption(mWindowManager.getGameSettingString("sCancel", "")); - cancelButton->eventMouseButtonClick = MyGUI::newDelegate(this, &SelectSkillDialog::onCancelClicked); + cancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectSkillDialog::onCancelClicked); } // widget controls @@ -850,7 +850,7 @@ DescriptionDialog::DescriptionDialog(WindowManager& parWindowManager) // TODO: These buttons should be managed by a Dialog class MyGUI::ButtonPtr okButton; getWidget(okButton, "OKButton"); - okButton->eventMouseButtonClick = MyGUI::newDelegate(this, &DescriptionDialog::onOkClicked); + okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &DescriptionDialog::onOkClicked); okButton->setCaption(mWindowManager.getGameSettingString("sInputMenu1", "")); // Make sure the edit box has focus diff --git a/apps/openmw/mwgui/class.hpp b/apps/openmw/mwgui/class.hpp index 5f1734b19..0e3348086 100644 --- a/apps/openmw/mwgui/class.hpp +++ b/apps/openmw/mwgui/class.hpp @@ -31,7 +31,7 @@ namespace MWGui int getChosenButton() const; // Events - typedef delegates::CDelegate1 EventHandle_Int; + typedef delegates::CMultiDelegate1 EventHandle_Int; /** Event : Button was clicked.\n signature : void method(MyGUI::WidgetPtr widget, int index)\n @@ -43,11 +43,11 @@ namespace MWGui private: - void fitToText(MyGUI::StaticTextPtr widget); + void fitToText(MyGUI::TextBox* widget); void layoutVertically(MyGUI::WidgetPtr widget, int margin); int currentButton; MyGUI::WidgetPtr textBox; - MyGUI::StaticTextPtr text; + MyGUI::TextBox* text; MyGUI::WidgetPtr buttonBar; std::vector buttons; }; @@ -78,7 +78,7 @@ namespace MWGui void open(); // Events - typedef delegates::CDelegate0 EventHandle_Void; + typedef delegates::CMultiDelegate0 EventHandle_Void; /** Event : Back button clicked.\n signature : void method()\n @@ -90,8 +90,8 @@ namespace MWGui void onBackClicked(MyGUI::Widget* _sender); private: - MyGUI::StaticImagePtr classImage; - MyGUI::StaticTextPtr className; + MyGUI::ImageBox* classImage; + MyGUI::TextBox* className; std::string currentClassId; }; @@ -108,7 +108,7 @@ namespace MWGui void open(); // Events - typedef delegates::CDelegate0 EventHandle_Void; + typedef delegates::CMultiDelegate0 EventHandle_Void; /** Event : Back button clicked.\n signature : void method()\n @@ -116,7 +116,7 @@ namespace MWGui EventHandle_Void eventBack; protected: - void onSelectClass(MyGUI::List* _sender, size_t _index); + void onSelectClass(MyGUI::ListBox* _sender, size_t _index); void onOkClicked(MyGUI::Widget* _sender); void onBackClicked(MyGUI::Widget* _sender); @@ -125,9 +125,9 @@ namespace MWGui void updateClasses(); void updateStats(); - MyGUI::StaticImagePtr classImage; - MyGUI::ListPtr classList; - MyGUI::StaticTextPtr specializationName; + MyGUI::ImageBox* classImage; + MyGUI::ListBox* classList; + MyGUI::TextBox* specializationName; Widgets::MWAttributePtr favoriteAttribute[2]; Widgets::MWSkillPtr majorSkill[5]; Widgets::MWSkillPtr minorSkill[5]; @@ -143,7 +143,7 @@ namespace MWGui ESM::Class::Specialization getSpecializationId() const { return specializationId; } // Events - typedef delegates::CDelegate0 EventHandle_Void; + typedef delegates::CMultiDelegate0 EventHandle_Void; /** Event : Cancel button clicked.\n signature : void method()\n @@ -160,7 +160,7 @@ namespace MWGui void onCancelClicked(MyGUI::Widget* _sender); private: - MyGUI::WidgetPtr specialization0, specialization1, specialization2; + MyGUI::TextBox *specialization0, *specialization1, *specialization2; ESM::Class::Specialization specializationId; }; @@ -175,7 +175,7 @@ namespace MWGui void setAffectedWidget(Widgets::MWAttributePtr widget) { affectedWidget = widget; } // Events - typedef delegates::CDelegate0 EventHandle_Void; + typedef delegates::CMultiDelegate0 EventHandle_Void; /** Event : Cancel button clicked.\n signature : void method()\n @@ -207,7 +207,7 @@ namespace MWGui void setAffectedWidget(Widgets::MWSkillPtr widget) { affectedWidget = widget; } // Events - typedef delegates::CDelegate0 EventHandle_Void; + typedef delegates::CMultiDelegate0 EventHandle_Void; /** Event : Cancel button clicked.\n signature : void method()\n @@ -264,7 +264,7 @@ namespace MWGui void open(); // Events - typedef delegates::CDelegate0 EventHandle_Void; + typedef delegates::CMultiDelegate0 EventHandle_Void; /** Event : Back button clicked.\n signature : void method()\n @@ -287,7 +287,7 @@ namespace MWGui private: MyGUI::EditPtr editName; - MyGUI::WidgetPtr specializationName; + MyGUI::TextBox* specializationName; Widgets::MWAttributePtr favoriteAttribute0, favoriteAttribute1; Widgets::MWSkillPtr majorSkill[5]; Widgets::MWSkillPtr minorSkill[5]; diff --git a/apps/openmw/mwgui/console.cpp b/apps/openmw/mwgui/console.cpp index 3fd6e7892..ac4f4a82a 100644 --- a/apps/openmw/mwgui/console.cpp +++ b/apps/openmw/mwgui/console.cpp @@ -113,9 +113,9 @@ namespace MWGui getWidget(history, "list_History"); // Set up the command line box - command->eventEditSelectAccept = + command->eventEditSelectAccept += newDelegate(this, &Console::acceptCommand); - command->eventKeyButtonPressed = + command->eventKeyButtonPressed += newDelegate(this, &Console::keyPress); // Set up the log window @@ -139,6 +139,9 @@ namespace MWGui void Console::disable() { setVisible(false); + // Remove keyboard focus from the console input whenever the + // console is turned off + MyGUI::InputManager::getInstance().setKeyFocusWidget(NULL); } void Console::setFont(const std::string &fntName) diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp index cef47d074..ac6681e27 100644 --- a/apps/openmw/mwgui/dialogue.cpp +++ b/apps/openmw/mwgui/dialogue.cpp @@ -43,24 +43,28 @@ DialogueWindow::DialogueWindow(WindowManager& parWindowManager,MWWorld::Environm // Centre dialog center(); - //WindowManager *wm = environment.mWindowManager; - setText("NpcName", "Name of character"); - //History view getWidget(history, "History"); history->setOverflowToTheLeft(true); - history->getClient()->eventMouseButtonClick = MyGUI::newDelegate(this, &DialogueWindow::onHistoryClicked); history->setMaxTextLength(1000000); + Widget* eventbox; + + //An EditBox cannot receive mouse click events, so we use an + //invisible widget on top of the editbox to receive them + /// \todo scrolling the dialogue history with the mouse wheel doesn't work using this solution + getWidget(eventbox, "EventBox"); + eventbox->eventMouseButtonClick += MyGUI::newDelegate(this, &DialogueWindow::onHistoryClicked); + //Topics list getWidget(topicsList, "TopicsList"); topicsList->setScrollVisible(true); - //topicsList->eventListSelectAccept = MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic); - topicsList->eventListMouseItemActivate = MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic); - //topicsList->eventListChangePosition = MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic); + //topicsList->eventListSelectAccept += MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic); + topicsList->eventListMouseItemActivate += MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic); + //topicsList->eventListChangePosition += MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic); MyGUI::ButtonPtr byeButton; getWidget(byeButton, "ByeButton"); - byeButton->eventMouseButtonClick = MyGUI::newDelegate(this, &DialogueWindow::onByeClicked); + byeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &DialogueWindow::onByeClicked); getWidget(pDispositionBar, "Disposition"); getWidget(pDispositionText,"DispositionText"); @@ -68,11 +72,11 @@ DialogueWindow::DialogueWindow(WindowManager& parWindowManager,MWWorld::Environm void DialogueWindow::onHistoryClicked(MyGUI::Widget* _sender) { - ISubWidgetText* t = history->getSubWidgetText(); + ISubWidgetText* t = history->getClient()->getSubWidgetText(); if(t == nullptr) return; - const IntPoint& lastPressed = InputManager::getInstance().getLastLeftPressed(); + const IntPoint& lastPressed = InputManager::getInstance().getLastPressedPosition(MyGUI::MouseButton::Left); size_t cursorPosition = t->getCursorPosition(lastPressed); MyGUI::UString color = history->getColorAtPos(cursorPosition); @@ -99,7 +103,7 @@ void DialogueWindow::onByeClicked(MyGUI::Widget* _sender) mEnvironment.mDialogueManager->goodbyeSelected(); } -void DialogueWindow::onSelectTopic(MyGUI::List* _sender, size_t _index) +void DialogueWindow::onSelectTopic(MyGUI::ListBox* _sender, size_t _index) { if (_index == MyGUI::ITEM_NONE) return; @@ -109,7 +113,8 @@ void DialogueWindow::onSelectTopic(MyGUI::List* _sender, size_t _index) void DialogueWindow::startDialogue(std::string npcName) { - setText("NpcName", npcName); + static_cast(mMainWidget)->setCaption(npcName); + adjustWindowCaption(); } void DialogueWindow::setKeywords(std::list keyWords) diff --git a/apps/openmw/mwgui/dialogue.hpp b/apps/openmw/mwgui/dialogue.hpp index 7dfd7bb7f..b80a016cb 100644 --- a/apps/openmw/mwgui/dialogue.hpp +++ b/apps/openmw/mwgui/dialogue.hpp @@ -21,7 +21,7 @@ namespace MWWorld namespace MWGui { - class DialogeHistory; + class DialogueHistory; using namespace MyGUI; @@ -33,7 +33,7 @@ namespace MWGui void open(); // Events - typedef delegates::CDelegate0 EventHandle_Void; + typedef delegates::CMultiDelegate0 EventHandle_Void; /** Event : Dialog finished, OK button clicked.\n signature : void method()\n @@ -49,7 +49,7 @@ namespace MWGui void askQuestion(std::string question); protected: - void onSelectTopic(MyGUI::List* _sender, size_t _index); + void onSelectTopic(MyGUI::ListBox* _sender, size_t _index); void onByeClicked(MyGUI::Widget* _sender); void onHistoryClicked(MyGUI::Widget* _sender); @@ -60,8 +60,8 @@ namespace MWGui */ std::string parseText(std::string text); - DialogeHistory* history; - MyGUI::ListPtr topicsList; + DialogueHistory* history; + MyGUI::ListBox* topicsList; MyGUI::ProgressPtr pDispositionBar; MyGUI::EditPtr pDispositionText; std::map pTopicsText;// this map links keyword and "real" text. diff --git a/apps/openmw/mwgui/dialogue_history.cpp b/apps/openmw/mwgui/dialogue_history.cpp index ceb904528..cd34ee119 100644 --- a/apps/openmw/mwgui/dialogue_history.cpp +++ b/apps/openmw/mwgui/dialogue_history.cpp @@ -13,10 +13,10 @@ using namespace MWGui; using namespace Widgets; -UString DialogeHistory::getColorAtPos(size_t _pos) +UString DialogueHistory::getColorAtPos(size_t _pos) { - UString colour = TextIterator::convertTagColour(mText->getTextColour()); - TextIterator iterator(mText->getCaption()); + UString colour = TextIterator::convertTagColour(getTextColour()); + TextIterator iterator(getCaption()); while(iterator.moveNext()) { size_t pos = iterator.getPosition(); @@ -29,12 +29,12 @@ UString DialogeHistory::getColorAtPos(size_t _pos) return colour; } -UString DialogeHistory::getColorTextAt(size_t _pos) +UString DialogueHistory::getColorTextAt(size_t _pos) { bool breakOnNext = false; - UString colour = TextIterator::convertTagColour(mText->getTextColour()); + UString colour = TextIterator::convertTagColour(getTextColour()); UString colour2 = colour; - TextIterator iterator(mText->getCaption()); + TextIterator iterator(getCaption()); TextIterator col_start = iterator; while(iterator.moveNext()) { @@ -59,7 +59,7 @@ UString DialogeHistory::getColorTextAt(size_t _pos) return ""; } -void DialogeHistory::addDialogHeading(const UString& parText) +void DialogueHistory::addDialogHeading(const UString& parText) { UString head("\n#D8C09A"); head.append(parText); @@ -67,7 +67,7 @@ void DialogeHistory::addDialogHeading(const UString& parText) addText(head); } -void DialogeHistory::addDialogText(const UString& parText) +void DialogueHistory::addDialogText(const UString& parText) { addText(parText); addText("\n"); diff --git a/apps/openmw/mwgui/dialogue_history.hpp b/apps/openmw/mwgui/dialogue_history.hpp index ec41678e6..12a9c53e7 100644 --- a/apps/openmw/mwgui/dialogue_history.hpp +++ b/apps/openmw/mwgui/dialogue_history.hpp @@ -5,9 +5,9 @@ namespace MWGui { using namespace MyGUI; - class DialogeHistory : public MyGUI::Edit + class DialogueHistory : public MyGUI::EditBox { - MYGUI_RTTI_DERIVED( DialogeHistory ) + MYGUI_RTTI_DERIVED( DialogueHistory ) public: Widget* getClient() { return mClient; } UString getColorAtPos(size_t _pos); diff --git a/apps/openmw/mwgui/journalwindow.cpp b/apps/openmw/mwgui/journalwindow.cpp index 5c9ef1f9b..644bcbc04 100644 --- a/apps/openmw/mwgui/journalwindow.cpp +++ b/apps/openmw/mwgui/journalwindow.cpp @@ -89,9 +89,9 @@ MWGui::JournalWindow::JournalWindow (WindowManager& parWindowManager) getWidget(mLeftTextWidget, "LeftText"); getWidget(mRightTextWidget, "RightText"); getWidget(mPrevBtn, "PrevPageBTN"); - mPrevBtn->eventMouseButtonClick = MyGUI::newDelegate(this,&MWGui::JournalWindow::notifyPrevPage); + mPrevBtn->eventMouseButtonClick += MyGUI::newDelegate(this,&MWGui::JournalWindow::notifyPrevPage); getWidget(mNextBtn, "NextPageBTN"); - mNextBtn->eventMouseButtonClick = MyGUI::newDelegate(this,&MWGui::JournalWindow::notifyNextPage); + mNextBtn->eventMouseButtonClick += MyGUI::newDelegate(this,&MWGui::JournalWindow::notifyNextPage); //MyGUI::ItemBox* list = new MyGUI::ItemBox(); //list->addItem("qaq","aqzazaz"); //mScrollerWidget->addChildItem(list); @@ -111,7 +111,7 @@ MWGui::JournalWindow::JournalWindow (WindowManager& parWindowManager) //displayLeftText(list.front()); MyGUI::WindowPtr t = static_cast(mMainWidget); - t->eventWindowChangeCoord = MyGUI::newDelegate(this, &JournalWindow::onWindowResize); + t->eventWindowChangeCoord += MyGUI::newDelegate(this, &JournalWindow::onWindowResize); } void MWGui::JournalWindow::open() diff --git a/apps/openmw/mwgui/journalwindow.hpp b/apps/openmw/mwgui/journalwindow.hpp index e66448763..4656c7a48 100644 --- a/apps/openmw/mwgui/journalwindow.hpp +++ b/apps/openmw/mwgui/journalwindow.hpp @@ -41,7 +41,7 @@ namespace MWGui static const int lineHeight; MyGUI::WidgetPtr skillAreaWidget, skillClientWidget; - MyGUI::VScrollPtr skillScrollerWidget; + MyGUI::ScrollBar* skillScrollerWidget; int lastPos, clientHeight; MyGUI::EditPtr mLeftTextWidget; MyGUI::EditPtr mRightTextWidget; @@ -54,4 +54,4 @@ namespace MWGui } -#endif \ No newline at end of file +#endif diff --git a/apps/openmw/mwgui/layouts.cpp b/apps/openmw/mwgui/layouts.cpp index ebabc6faf..6d8aa901b 100644 --- a/apps/openmw/mwgui/layouts.cpp +++ b/apps/openmw/mwgui/layouts.cpp @@ -15,6 +15,27 @@ using namespace MWGui; HUD::HUD(int width, int height, int fpsLevel) : Layout("openmw_hud_layout.xml") + , health(NULL) + , magicka(NULL) + , stamina(NULL) + , weapImage(NULL) + , spellImage(NULL) + , weapStatus(NULL) + , spellStatus(NULL) + , effectBox(NULL) + , effect1(NULL) + , minimap(NULL) + , compass(NULL) + , crosshair(NULL) + , fpsbox(NULL) + , fpscounter(NULL) + , trianglecounter(NULL) + , batchcounter(NULL) + , hmsBaseLeft(0) + , weapBoxBaseLeft(0) + , spellBoxBaseLeft(0) + , effectBoxBaseRight(0) + , minimapBoxBaseRight(0) { setCoord(0,0, width, height); @@ -22,16 +43,25 @@ HUD::HUD(int width, int height, int fpsLevel) getWidget(health, "Health"); getWidget(magicka, "Magicka"); getWidget(stamina, "Stamina"); + hmsBaseLeft = health->getLeft(); // Item and spell images and status bars + getWidget(weapBox, "WeapBox"); getWidget(weapImage, "WeapImage"); getWidget(weapStatus, "WeapStatus"); + weapBoxBaseLeft = weapBox->getLeft(); + + getWidget(spellBox, "SpellBox"); getWidget(spellImage, "SpellImage"); getWidget(spellStatus, "SpellStatus"); + spellBoxBaseLeft = spellBox->getLeft(); getWidget(effectBox, "EffectBox"); getWidget(effect1, "Effect1"); + effectBoxBaseRight = effectBox->getRight(); + getWidget(minimapBox, "MiniMapBox"); + minimapBoxBaseRight = minimapBox->getRight(); getWidget(minimap, "MiniMap"); getWidget(compass, "Compass"); @@ -61,6 +91,8 @@ HUD::HUD(int width, int height, int fpsLevel) setSpellIcon("icons\\s\\b_tx_s_rstor_health.dds"); setSpellStatus(65, 100); setEffect("icons\\s\\tx_s_chameleon.dds"); + + LocalMapBase::init(minimap, this); } void HUD::setFPS(float fps) @@ -142,3 +174,146 @@ void HUD::setValue(const std::string& id, const MWMechanics::DynamicStat& v } } } + +void HUD::setPlayerDir(const float x, const float y) +{ + if (!minimapBox->getVisible() || (x == mLastPositionX && y == mLastPositionY)) return; + + MyGUI::ISubWidget* main = compass->getSubWidgetMain(); + MyGUI::RotatingSkin* rotatingSubskin = main->castType(); + rotatingSubskin->setCenter(MyGUI::IntPoint(16,16)); + float angle = std::atan2(x,y); + rotatingSubskin->setAngle(angle); + mLastPositionX = x; + mLastPositionY = y; +} + +void HUD::setPlayerPos(const float x, const float y) +{ + if (!minimapBox->getVisible() || (x == mLastDirectionX && y == mLastDirectionY)) return; + + MyGUI::IntSize size = minimap->getCanvasSize(); + MyGUI::IntPoint middle = MyGUI::IntPoint((1/3.f + x/3.f)*size.width,(1/3.f + y/3.f)*size.height); + MyGUI::IntCoord viewsize = minimap->getCoord(); + MyGUI::IntPoint pos(0.5*viewsize.width - middle.left, 0.5*viewsize.height - middle.top); + + minimap->setViewOffset(pos); + compass->setPosition(MyGUI::IntPoint(x*512-16, y*512-16)); + + mLastDirectionX = x; + mLastDirectionY = y; +} + +void HUD::setBottomLeftVisibility(bool hmsVisible, bool weapVisible, bool spellVisible) +{ + int weapDx = 0, spellDx = 0; + if (!hmsVisible) + spellDx = weapDx = weapBoxBaseLeft - hmsBaseLeft; + + if (!weapVisible) + spellDx -= spellBoxBaseLeft - weapBoxBaseLeft; + + health->setVisible(hmsVisible); + stamina->setVisible(hmsVisible); + magicka->setVisible(hmsVisible); + weapBox->setPosition(weapBoxBaseLeft - weapDx, weapBox->getTop()); + weapBox->setVisible(weapVisible); + spellBox->setPosition(spellBoxBaseLeft - spellDx, spellBox->getTop()); + spellBox->setVisible(spellVisible); +} + +void HUD::setBottomRightVisibility(bool effectBoxVisible, bool minimapBoxVisible) +{ + // effect box can have variable width -> variable left coordinate + int effectsDx = 0; + if (!minimapBoxVisible) + effectsDx = minimapBoxBaseRight - effectBoxBaseRight; + + minimapBox->setVisible(minimapBoxVisible); + effectBox->setPosition(effectBoxBaseRight - effectBox->getWidth() + effectsDx, effectBox->getTop()); + effectBox->setVisible(effectBoxVisible); +} + +LocalMapBase::LocalMapBase() + : mCurX(0) + , mCurY(0) + , mInterior(false) + , mFogOfWar(true) + , mLocalMap(NULL) + , mPrefix() + , mChanged(true) + , mLayout(NULL) + , mLastPositionX(0.0f) + , mLastPositionY(0.0f) + , mLastDirectionX(0.0f) + , mLastDirectionY(0.0f) +{ +} + +void LocalMapBase::init(MyGUI::ScrollView* widget, OEngine::GUI::Layout* layout) +{ + mLocalMap = widget; + mLayout = layout; +} + +void LocalMapBase::setCellPrefix(const std::string& prefix) +{ + mPrefix = prefix; + mChanged = true; +} + +void LocalMapBase::toggleFogOfWar() +{ + mFogOfWar = !mFogOfWar; + applyFogOfWar(); +} + +void LocalMapBase::applyFogOfWar() +{ + for (int mx=0; mx<3; ++mx) + { + for (int my=0; my<3; ++my) + { + std::string name = "Map_" + boost::lexical_cast(mx) + "_" + + boost::lexical_cast(my); + std::string image = mPrefix+"_"+ boost::lexical_cast(mCurX + (mx-1)) + "_" + + boost::lexical_cast(mCurY + (mInterior ? (my-1) : -1*(my-1))); + MyGUI::ImageBox* fog; + mLayout->getWidget(fog, name+"_fog"); + fog->setImageTexture(mFogOfWar ? + ((MyGUI::RenderManager::getInstance().getTexture(image+"_fog") != 0) ? image+"_fog" + : "black.png" ) + : ""); + } + } +} + +void LocalMapBase::setActiveCell(const int x, const int y, bool interior) +{ + if (x==mCurX && y==mCurY && mInterior==interior && !mChanged) return; // don't do anything if we're still in the same cell + for (int mx=0; mx<3; ++mx) + { + for (int my=0; my<3; ++my) + { + std::string name = "Map_" + boost::lexical_cast(mx) + "_" + + boost::lexical_cast(my); + + std::string image = mPrefix+"_"+ boost::lexical_cast(x + (mx-1)) + "_" + + boost::lexical_cast(y + (interior ? (my-1) : -1*(my-1))); + + MyGUI::ImageBox* box; + mLayout->getWidget(box, name); + + if (MyGUI::RenderManager::getInstance().getTexture(image) != 0) + box->setImageTexture(image); + else + box->setImageTexture("black.png"); + } + } + mInterior = interior; + mCurX = x; + mCurY = y; + mChanged = false; + applyFogOfWar(); +} + diff --git a/apps/openmw/mwgui/layouts.hpp b/apps/openmw/mwgui/layouts.hpp index 9917dcdcc..0614708cf 100644 --- a/apps/openmw/mwgui/layouts.hpp +++ b/apps/openmw/mwgui/layouts.hpp @@ -14,6 +14,8 @@ #include "../mwmechanics/stat.hpp" #include "window_base.hpp" +#include + /* This file contains classes corresponding to window layouts defined in resources/mygui/ *.xml. @@ -29,7 +31,36 @@ namespace MWGui { - class HUD : public OEngine::GUI::Layout + class LocalMapBase + { + public: + LocalMapBase(); + void init(MyGUI::ScrollView* widget, OEngine::GUI::Layout* layout); + + void setCellPrefix(const std::string& prefix); + void setActiveCell(const int x, const int y, bool interior=false); + + void toggleFogOfWar(); + + protected: + int mCurX, mCurY; + bool mInterior; + MyGUI::ScrollView* mLocalMap; + std::string mPrefix; + bool mChanged; + bool mFogOfWar; + + void applyFogOfWar(); + + OEngine::GUI::Layout* mLayout; + + float mLastPositionX; + float mLastPositionY; + float mLastDirectionX; + float mLastDirectionY; + }; + + class HUD : public OEngine::GUI::Layout, public LocalMapBase { public: HUD(int width, int height, int fpsLevel); @@ -43,40 +74,31 @@ namespace MWGui void setFPS(float fps); void setTriangleCount(size_t count); void setBatchCount(size_t count); + void setPlayerDir(const float x, const float y); + void setPlayerPos(const float x, const float y); + void setBottomLeftVisibility(bool hmsVisible, bool weapVisible, bool spellVisible); + void setBottomRightVisibility(bool effectBoxVisible, bool minimapVisible); MyGUI::ProgressPtr health, magicka, stamina; - MyGUI::StaticImagePtr weapImage, spellImage; + MyGUI::Widget *weapBox, *spellBox; + MyGUI::ImageBox *weapImage, *spellImage; MyGUI::ProgressPtr weapStatus, spellStatus; - MyGUI::WidgetPtr effectBox; - MyGUI::StaticImagePtr effect1; - MyGUI::StaticImagePtr minimap; - MyGUI::StaticImagePtr compass; - MyGUI::StaticImagePtr crosshair; + MyGUI::Widget *effectBox, *minimapBox; + MyGUI::ImageBox* effect1; + MyGUI::ScrollView* minimap; + MyGUI::ImageBox* compass; + MyGUI::ImageBox* crosshair; MyGUI::WidgetPtr fpsbox; - MyGUI::StaticTextPtr fpscounter; - MyGUI::StaticTextPtr trianglecounter; - MyGUI::StaticTextPtr batchcounter; - }; - - class MapWindow : public OEngine::GUI::Layout - { - public: - MapWindow() - : Layout("openmw_map_window_layout.xml") - { - setCoord(500,0,320,300); - setText("WorldButton", "World"); - setImage("Compass", "compass.dds"); - - // Obviously you should override this later on - setCellName("No Cell Loaded"); - } - - void setCellName(const std::string& cellName) - { - mMainWidget->setCaption(cellName); - } + MyGUI::TextBox* fpscounter; + MyGUI::TextBox* trianglecounter; + MyGUI::TextBox* batchcounter; + + private: + // bottom left elements + int hmsBaseLeft, weapBoxBaseLeft, spellBoxBaseLeft; + // bottom right elements + int minimapBoxBaseRight, effectBoxBaseRight; }; class MainMenu : public OEngine::GUI::Layout @@ -127,7 +149,7 @@ namespace MWGui getWidget(avatar, "Avatar"); // Adjust armor rating text to bottom of avatar widget - MyGUI::StaticTextPtr armor_rating; + MyGUI::TextBox* armor_rating; getWidget(armor_rating, "ArmorRating"); armor_rating->setCaption("Armor: 11"); MyGUI::IntCoord coord = armor_rating->getCoord(); @@ -165,7 +187,7 @@ namespace MWGui last_x += coord.width + margin; button_pt->setCoord(coord); - button_pt->eventMouseButtonClick = MyGUI::newDelegate(this, &InventoryWindow::onCategorySelected); + button_pt->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onCategorySelected); } } diff --git a/apps/openmw/mwgui/map_window.cpp b/apps/openmw/mwgui/map_window.cpp new file mode 100644 index 000000000..0e9d57c3c --- /dev/null +++ b/apps/openmw/mwgui/map_window.cpp @@ -0,0 +1,106 @@ +#include "map_window.hpp" +#include "window_manager.hpp" +/* +#include "../mwmechanics/mechanicsmanager.hpp" + +#include +#include +#include + +#undef min +#undef max +*/ +using namespace MWGui; + +MapWindow::MapWindow(WindowManager& parWindowManager) : + MWGui::WindowPinnableBase("openmw_map_window_layout.xml", parWindowManager), + mGlobal(false) +{ + setCoord(500,0,320,300); + setText("WorldButton", "World"); + setImage("Compass", "textures\\compass.dds"); + + // Obviously you should override this later on + setCellName("No Cell Loaded"); + + getWidget(mLocalMap, "LocalMap"); + getWidget(mGlobalMap, "GlobalMap"); + getWidget(mPlayerArrow, "Compass"); + + getWidget(mButton, "WorldButton"); + mButton->eventMouseButtonClick += MyGUI::newDelegate(this, &MapWindow::onWorldButtonClicked); + + MyGUI::Button* eventbox; + getWidget(eventbox, "EventBox"); + eventbox->eventMouseDrag += MyGUI::newDelegate(this, &MapWindow::onMouseDrag); + eventbox->eventMouseButtonPressed += MyGUI::newDelegate(this, &MapWindow::onDragStart); + + LocalMapBase::init(mLocalMap, this); +} + +void MapWindow::setCellName(const std::string& cellName) +{ + static_cast(mMainWidget)->setCaption(cellName); + adjustWindowCaption(); +} + +void MapWindow::setPlayerPos(const float x, const float y) +{ + if (mGlobal || !mVisible || (x == mLastPositionX && y == mLastPositionY)) return; + MyGUI::IntSize size = mLocalMap->getCanvasSize(); + MyGUI::IntPoint middle = MyGUI::IntPoint((1/3.f + x/3.f)*size.width,(1/3.f + y/3.f)*size.height); + MyGUI::IntCoord viewsize = mLocalMap->getCoord(); + MyGUI::IntPoint pos(0.5*viewsize.width - middle.left, 0.5*viewsize.height - middle.top); + mLocalMap->setViewOffset(pos); + + mPlayerArrow->setPosition(MyGUI::IntPoint(x*512-16, y*512-16)); + mLastPositionX = x; + mLastPositionY = y; +} + +void MapWindow::setPlayerDir(const float x, const float y) +{ + if (!mVisible || (x == mLastDirectionX && y == mLastDirectionY)) return; + MyGUI::ISubWidget* main = mPlayerArrow->getSubWidgetMain(); + MyGUI::RotatingSkin* rotatingSubskin = main->castType(); + rotatingSubskin->setCenter(MyGUI::IntPoint(16,16)); + float angle = std::atan2(x,y); + rotatingSubskin->setAngle(angle); + + mLastDirectionX = x; + mLastDirectionY = y; +} + +void MapWindow::onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id) +{ + if (_id!=MyGUI::MouseButton::Left) return; + if (!mGlobal) + mLastDragPos = MyGUI::IntPoint(_left, _top); +} + +void MapWindow::onMouseDrag(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id) +{ + if (_id!=MyGUI::MouseButton::Left) return; + + if (!mGlobal) + { + MyGUI::IntPoint diff = MyGUI::IntPoint(_left, _top) - mLastDragPos; + mLocalMap->setViewOffset( mLocalMap->getViewOffset() + diff ); + + mLastDragPos = MyGUI::IntPoint(_left, _top); + } +} + +void MapWindow::onWorldButtonClicked(MyGUI::Widget* _sender) +{ + mGlobal = !mGlobal; + mGlobalMap->setVisible(mGlobal); + mLocalMap->setVisible(!mGlobal); + + mButton->setCaption( mGlobal ? "Local" : "World" ); +} + +void MapWindow::onPinToggled() +{ + mWindowManager.setMinimapVisibility(!mPinned); +} diff --git a/apps/openmw/mwgui/map_window.hpp b/apps/openmw/mwgui/map_window.hpp new file mode 100644 index 000000000..d14221a40 --- /dev/null +++ b/apps/openmw/mwgui/map_window.hpp @@ -0,0 +1,34 @@ +#ifndef MWGUI_MAPWINDOW_H +#define MWGUI_MAPWINDOW_H + +#include "layouts.hpp" +#include "window_pinnable_base.hpp" + +namespace MWGui +{ + class MapWindow : public MWGui::WindowPinnableBase, public LocalMapBase + { + public: + MapWindow(WindowManager& parWindowManager); + virtual ~MapWindow(){} + + void setPlayerPos(const float x, const float y); + void setPlayerDir(const float x, const float y); + void setCellName(const std::string& cellName); + + private: + void onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id); + void onMouseDrag(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id); + void onWorldButtonClicked(MyGUI::Widget* _sender); + + MyGUI::ScrollView* mGlobalMap; + MyGUI::ImageBox* mPlayerArrow; + MyGUI::Button* mButton; + MyGUI::IntPoint mLastDragPos; + bool mGlobal; + + protected: + virtual void onPinToggled(); + }; +} +#endif diff --git a/apps/openmw/mwgui/messagebox.cpp b/apps/openmw/mwgui/messagebox.cpp index f0745bbbe..c103bcb8b 100644 --- a/apps/openmw/mwgui/messagebox.cpp +++ b/apps/openmw/mwgui/messagebox.cpp @@ -19,7 +19,7 @@ void MessageBoxManager::onFrame (float frameDuration) if(it->current >= it->max) { it->messageBox->mMarkedToDelete = true; - + if(*mMessageBoxes.begin() == it->messageBox) // if this box is the last one { // collect all with mMarkedToDelete and delete them. @@ -47,7 +47,7 @@ void MessageBoxManager::onFrame (float frameDuration) it++; } } - + if(mInterMessageBoxe != NULL && mInterMessageBoxe->mMarkedToDelete) { delete mInterMessageBoxe; mInterMessageBoxe = NULL; @@ -57,20 +57,18 @@ void MessageBoxManager::onFrame (float frameDuration) void MessageBoxManager::createMessageBox (const std::string& message) { - std::cout << "MessageBox: " << message << std::endl; - MessageBox *box = new MessageBox(*this, message); - + removeMessageBox(message.length()*mMessageBoxSpeed, box); - + mMessageBoxes.push_back(box); std::vector::iterator it; - + if(mMessageBoxes.size() > 3) { delete *mMessageBoxes.begin(); mMessageBoxes.erase(mMessageBoxes.begin()); } - + int height = 0; for(it = mMessageBoxes.begin(); it != mMessageBoxes.end(); ++it) { @@ -88,9 +86,9 @@ bool MessageBoxManager::createInteractiveMessageBox (const std::string& message, std::cout << "interactive MessageBox: " << message << " - "; std::copy (buttons.begin(), buttons.end(), std::ostream_iterator (std::cout, ", ")); std::cout << std::endl; - + mInterMessageBoxe = new InteractiveMessageBox(*this, message, buttons); - + return true; } @@ -105,7 +103,7 @@ void MessageBoxManager::removeMessageBox (float time, MessageBox *msgbox) timer.current = 0; timer.max = time; timer.messageBox = msgbox; - + mTimers.insert(mTimers.end(), timer); } @@ -152,25 +150,26 @@ MessageBox::MessageBox(MessageBoxManager& parMessageBoxManager, const std::strin mBottomPadding = 20; mNextBoxPadding = 20; mMarkedToDelete = false; - + getWidget(mMessageWidget, "message"); - + mMessageWidget->setOverflowToTheLeft(true); mMessageWidget->addText(cMessage); - + MyGUI::IntSize size; size.width = mFixedWidth; size.height = 100; // dummy - + MyGUI::IntCoord coord; coord.left = 10; // dummy coord.top = 10; // dummy mMessageWidget->setSize(size); - - MyGUI::IntSize textSize = mMessageWidget->_getTextSize(); + + MyGUI::IntSize textSize = mMessageWidget->getTextSize(); + size.height = mHeight = textSize.height + 20; // this is the padding between the text and the box - + mMainWidget->setSize(size); size.width -= 15; // this is to center the text (see messagebox_layout.xml, Widget type="Edit" position="-2 -3 0 0") mMessageWidget->setSize(size); @@ -178,15 +177,15 @@ MessageBox::MessageBox(MessageBoxManager& parMessageBoxManager, const std::strin void MessageBox::update (int height) { - MyGUI::IntSize gameWindowSize = mMessageBoxManager.mWindowManager->getGui()->getViewSize(); + MyGUI::IntSize gameWindowSize = MyGUI::RenderManager::getInstance().getViewSize(); MyGUI::IntCoord coord; coord.left = (gameWindowSize.width - mFixedWidth)/2; coord.top = (gameWindowSize.height - mHeight - height - mBottomPadding); - + MyGUI::IntSize size; size.width = mFixedWidth; size.height = mHeight; - + mMainWidget->setCoord(coord); mMainWidget->setSize(size); mMainWidget->setVisible(true); @@ -211,26 +210,26 @@ InteractiveMessageBox::InteractiveMessageBox(MessageBoxManager& parMessageBoxMan int buttonTopPadding = 5; // ^-- if vertical int buttonPadding = 5; // padding between button label and button itself int buttonMainPadding = 10; // padding between buttons and bottom of the main widget - + mMarkedToDelete = false; - - + + getWidget(mMessageWidget, "message"); getWidget(mButtonsWidget, "buttons"); - + mMessageWidget->setOverflowToTheLeft(true); mMessageWidget->addText(message); - - MyGUI::IntSize textSize = mMessageWidget->_getTextSize(); - - MyGUI::IntSize gameWindowSize = mMessageBoxManager.mWindowManager->getGui()->getViewSize(); - + + MyGUI::IntSize textSize = mMessageWidget->getTextSize(); + + MyGUI::IntSize gameWindowSize = MyGUI::RenderManager::getInstance().getViewSize(); + int biggestButtonWidth = 0; int buttonWidth = 0; int buttonsWidth = 0; int buttonHeight = 0; MyGUI::IntCoord dummyCoord(0, 0, 0, 0); - + std::vector::const_iterator it; for(it = buttons.begin(); it != buttons.end(); ++it) { @@ -240,28 +239,28 @@ InteractiveMessageBox::InteractiveMessageBox(MessageBoxManager& parMessageBoxMan dummyCoord, MyGUI::Align::Default); button->setCaption(*it); - - button->eventMouseButtonClick = MyGUI::newDelegate(this, &InteractiveMessageBox::mousePressed); - + + button->eventMouseButtonClick += MyGUI::newDelegate(this, &InteractiveMessageBox::mousePressed); + mButtons.push_back(button); - - buttonWidth = button->_getTextSize().width + 2*buttonPadding + buttonLeftPadding; + + buttonWidth = button->getTextSize().width + 2*buttonPadding + buttonLeftPadding; buttonsWidth += buttonWidth; - buttonHeight = button->_getTextSize().height + 2*buttonPadding + buttonTopPadding; - + buttonHeight = button->getTextSize().height + 2*buttonPadding + buttonTopPadding; + if(buttonWidth > biggestButtonWidth) { biggestButtonWidth = buttonWidth; } } buttonsWidth += buttonLeftPadding; - + MyGUI::IntSize mainWidgetSize; if(buttonsWidth < fixedWidth) { // on one line std::cout << "on one line" << std::endl; - + if(textSize.width + 2*textPadding < buttonsWidth) { std::cout << "width = buttonsWidth" << std::endl; @@ -272,48 +271,48 @@ InteractiveMessageBox::InteractiveMessageBox(MessageBoxManager& parMessageBoxMan mainWidgetSize.width = textSize.width + 3*textPadding; } mainWidgetSize.height = textSize.height + textButtonPadding + buttonHeight + buttonMainPadding; - + MyGUI::IntCoord absCoord; absCoord.left = (gameWindowSize.width - mainWidgetSize.width)/2; absCoord.top = (gameWindowSize.height - mainWidgetSize.height)/2; - + std::cout << "width " << mainWidgetSize.width << " height " << mainWidgetSize.height << std::endl; std::cout << "left " << absCoord.left << " top " << absCoord.top << std::endl; - + mMainWidget->setCoord(absCoord); mMainWidget->setSize(mainWidgetSize); - - + + MyGUI::IntCoord messageWidgetCoord; messageWidgetCoord.left = (mainWidgetSize.width - textSize.width)/2; messageWidgetCoord.top = textPadding; mMessageWidget->setCoord(messageWidgetCoord); - + mMessageWidget->setSize(textSize); - + MyGUI::IntCoord buttonCord; MyGUI::IntSize buttonSize(0, buttonHeight); int left = (mainWidgetSize.width - buttonsWidth)/2 + buttonPadding; - + std::vector::const_iterator button; for(button = mButtons.begin(); button != mButtons.end(); ++button) { buttonCord.left = left; buttonCord.top = textSize.height + textButtonPadding; - - buttonSize.width = (*button)->_getTextSize().width + 2*buttonPadding; - buttonSize.height = (*button)->_getTextSize().height + 2*buttonPadding; - + + buttonSize.width = (*button)->getTextSize().width + 2*buttonPadding; + buttonSize.height = (*button)->getTextSize().height + 2*buttonPadding; + (*button)->setCoord(buttonCord); (*button)->setSize(buttonSize); - + left += buttonSize.width + buttonLeftPadding; } } else { // among each other - + if(biggestButtonWidth > textSize.width) { mainWidgetSize.width = biggestButtonWidth + buttonTopPadding; } @@ -321,46 +320,46 @@ InteractiveMessageBox::InteractiveMessageBox(MessageBoxManager& parMessageBoxMan mainWidgetSize.width = textSize.width + 3*textPadding; } mainWidgetSize.height = textSize.height + 2*textPadding + textButtonPadding + buttonHeight * buttons.size() + buttonMainPadding; - + std::cout << "biggestButtonWidth " << biggestButtonWidth << " textSize.width " << textSize.width << std::endl; std::cout << "width " << mainWidgetSize.width << " height " << mainWidgetSize.height << std::endl; mMainWidget->setSize(mainWidgetSize); - + MyGUI::IntCoord absCoord; absCoord.left = (gameWindowSize.width - mainWidgetSize.width)/2; absCoord.top = (gameWindowSize.height - mainWidgetSize.height)/2; - + mMainWidget->setCoord(absCoord); mMainWidget->setSize(mainWidgetSize); - - + + MyGUI::IntCoord messageWidgetCoord; messageWidgetCoord.left = (mainWidgetSize.width - textSize.width)/2; messageWidgetCoord.top = textPadding; mMessageWidget->setCoord(messageWidgetCoord); - + mMessageWidget->setSize(textSize); - + MyGUI::IntCoord buttonCord; MyGUI::IntSize buttonSize(0, buttonHeight); - + int top = textButtonPadding + buttonTopPadding + textSize.height; - + std::vector::const_iterator button; for(button = mButtons.begin(); button != mButtons.end(); ++button) { - buttonSize.width = (*button)->_getTextSize().width + buttonPadding*2; - buttonSize.height = (*button)->_getTextSize().height + buttonPadding*2; - + buttonSize.width = (*button)->getTextSize().width + buttonPadding*2; + buttonSize.height = (*button)->getTextSize().height + buttonPadding*2; + buttonCord.top = top; buttonCord.left = (mainWidgetSize.width - buttonSize.width)/2 - 5; // FIXME: -5 is not so nice :/ - + (*button)->setCoord(buttonCord); (*button)->setSize(buttonSize); - + top += buttonSize.height + 2*buttonTopPadding; } - + } } @@ -387,8 +386,3 @@ int InteractiveMessageBox::readPressedButton () mButtonPressed = -1; return pressed; } - - - - - diff --git a/apps/openmw/mwgui/messagebox.hpp b/apps/openmw/mwgui/messagebox.hpp index bf3307acc..33155b2a0 100644 --- a/apps/openmw/mwgui/messagebox.hpp +++ b/apps/openmw/mwgui/messagebox.hpp @@ -7,6 +7,7 @@ #include "window_base.hpp" #include "window_manager.hpp" +#undef MessageBox namespace MWGui { diff --git a/apps/openmw/mwgui/race.cpp b/apps/openmw/mwgui/race.cpp index 037f97fc3..880c0bc52 100644 --- a/apps/openmw/mwgui/race.cpp +++ b/apps/openmw/mwgui/race.cpp @@ -34,7 +34,7 @@ RaceDialog::RaceDialog(WindowManager& parWindowManager) headRotate->setScrollRange(50); headRotate->setScrollPosition(20); headRotate->setScrollViewPage(10); - headRotate->eventScrollChangePosition = MyGUI::newDelegate(this, &RaceDialog::onHeadRotate); + headRotate->eventScrollChangePosition += MyGUI::newDelegate(this, &RaceDialog::onHeadRotate); // Set up next/previous buttons MyGUI::ButtonPtr prevButton, nextButton; @@ -42,27 +42,27 @@ RaceDialog::RaceDialog(WindowManager& parWindowManager) 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); + prevButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onSelectPreviousGender); + nextButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onSelectNextGender); 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); + prevButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onSelectPreviousFace); + nextButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onSelectNextFace); 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); + prevButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onSelectPreviousHair); + nextButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onSelectNextHair); 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); + raceList->eventListSelectAccept += MyGUI::newDelegate(this, &RaceDialog::onSelectRace); + raceList->eventListMouseItemActivate += MyGUI::newDelegate(this, &RaceDialog::onSelectRace); + raceList->eventListChangePosition += MyGUI::newDelegate(this, &RaceDialog::onSelectRace); setText("SkillsT", mWindowManager.getGameSettingString("sBonusSkillTitle", "Skill Bonus")); getWidget(skillList, "SkillList"); @@ -72,11 +72,11 @@ RaceDialog::RaceDialog(WindowManager& parWindowManager) // TODO: These buttons should be managed by a Dialog class MyGUI::ButtonPtr backButton; getWidget(backButton, "BackButton"); - backButton->eventMouseButtonClick = MyGUI::newDelegate(this, &RaceDialog::onBackClicked); + backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onBackClicked); MyGUI::ButtonPtr okButton; getWidget(okButton, "OKButton"); - okButton->eventMouseButtonClick = MyGUI::newDelegate(this, &RaceDialog::onOkClicked); + okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onOkClicked); updateRaces(); updateSkills(); @@ -157,7 +157,7 @@ void RaceDialog::onBackClicked(MyGUI::Widget* _sender) eventBack(); } -void RaceDialog::onHeadRotate(MyGUI::VScroll*, size_t _position) +void RaceDialog::onHeadRotate(MyGUI::ScrollBar*, size_t _position) { // TODO: Rotate head } @@ -192,7 +192,7 @@ void RaceDialog::onSelectNextHair(MyGUI::Widget*) hairIndex = wrap(hairIndex - 1, hairCount); } -void RaceDialog::onSelectRace(MyGUI::List* _sender, size_t _index) +void RaceDialog::onSelectRace(MyGUI::ListBox* _sender, size_t _index) { if (_index == MyGUI::ITEM_NONE) return; diff --git a/apps/openmw/mwgui/race.hpp b/apps/openmw/mwgui/race.hpp index f2aac3a18..bcd3b5185 100644 --- a/apps/openmw/mwgui/race.hpp +++ b/apps/openmw/mwgui/race.hpp @@ -46,7 +46,7 @@ namespace MWGui void open(); // Events - typedef delegates::CDelegate0 EventHandle_Void; + typedef delegates::CMultiDelegate0 EventHandle_Void; /** Event : Back button clicked.\n signature : void method()\n @@ -54,7 +54,7 @@ namespace MWGui EventHandle_Void eventBack; protected: - void onHeadRotate(MyGUI::VScroll* _sender, size_t _position); + void onHeadRotate(MyGUI::ScrollBar* _sender, size_t _position); void onSelectPreviousGender(MyGUI::Widget* _sender); void onSelectNextGender(MyGUI::Widget* _sender); @@ -65,7 +65,7 @@ namespace MWGui void onSelectPreviousHair(MyGUI::Widget* _sender); void onSelectNextHair(MyGUI::Widget* _sender); - void onSelectRace(MyGUI::List* _sender, size_t _index); + void onSelectRace(MyGUI::ListBox* _sender, size_t _index); void onOkClicked(MyGUI::Widget* _sender); void onBackClicked(MyGUI::Widget* _sender); @@ -76,8 +76,8 @@ namespace MWGui void updateSpellPowers(); MyGUI::CanvasPtr appearanceBox; - MyGUI::ListPtr raceList; - MyGUI::HScrollPtr headRotate; + MyGUI::ListBox* raceList; + MyGUI::ScrollBar* headRotate; MyGUI::WidgetPtr skillList; std::vector skillItems; diff --git a/apps/openmw/mwgui/review.cpp b/apps/openmw/mwgui/review.cpp index e770ec235..cb0d9969c 100644 --- a/apps/openmw/mwgui/review.cpp +++ b/apps/openmw/mwgui/review.cpp @@ -28,22 +28,22 @@ ReviewDialog::ReviewDialog(WindowManager& parWindowManager) getWidget(nameWidget, "NameText"); getWidget(button, "NameButton"); button->setCaption(mWindowManager.getGameSettingString("sName", "")); - button->eventMouseButtonClick = MyGUI::newDelegate(this, &ReviewDialog::onNameClicked);; + button->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onNameClicked);; getWidget(raceWidget, "RaceText"); getWidget(button, "RaceButton"); button->setCaption(mWindowManager.getGameSettingString("sRace", "")); - button->eventMouseButtonClick = MyGUI::newDelegate(this, &ReviewDialog::onRaceClicked);; + button->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onRaceClicked);; getWidget(classWidget, "ClassText"); getWidget(button, "ClassButton"); button->setCaption(mWindowManager.getGameSettingString("sClass", "")); - button->eventMouseButtonClick = MyGUI::newDelegate(this, &ReviewDialog::onClassClicked);; + button->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onClassClicked);; getWidget(birthSignWidget, "SignText"); getWidget(button, "SignButton"); button->setCaption(mWindowManager.getGameSettingString("sBirthSign", "")); - button->eventMouseButtonClick = MyGUI::newDelegate(this, &ReviewDialog::onBirthSignClicked);; + button->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onBirthSignClicked);; // Setup dynamic stats getWidget(health, "Health"); @@ -75,25 +75,25 @@ ReviewDialog::ReviewDialog(WindowManager& parWindowManager) getWidget(skillClientWidget, "SkillClient"); getWidget(skillScrollerWidget, "SkillScroller"); - skillScrollerWidget->eventScrollChangePosition = MyGUI::newDelegate(this, &ReviewDialog::onScrollChangePosition); + skillScrollerWidget->eventScrollChangePosition += MyGUI::newDelegate(this, &ReviewDialog::onScrollChangePosition); updateScroller(); 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))); + skillWidgetMap.insert(std::make_pair(i, static_cast (0))); } - static_cast(mMainWidget)->eventWindowChangeCoord = MyGUI::newDelegate(this, &ReviewDialog::onWindowResize); + static_cast(mMainWidget)->eventWindowChangeCoord += MyGUI::newDelegate(this, &ReviewDialog::onWindowResize); // TODO: These buttons should be managed by a Dialog class MyGUI::ButtonPtr backButton; getWidget(backButton, "BackButton"); - backButton->eventMouseButtonClick = MyGUI::newDelegate(this, &ReviewDialog::onBackClicked); + backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onBackClicked); MyGUI::ButtonPtr okButton; getWidget(okButton, "OKButton"); - okButton->eventMouseButtonClick = MyGUI::newDelegate(this, &ReviewDialog::onOkClicked); + okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onOkClicked); } void ReviewDialog::open() @@ -102,7 +102,7 @@ void ReviewDialog::open() setVisible(true); } -void ReviewDialog::onScrollChangePosition(MyGUI::VScrollPtr scroller, size_t pos) +void ReviewDialog::onScrollChangePosition(MyGUI::ScrollBar* scroller, size_t pos) { int diff = lastPos - pos; // Adjust position of all widget according to difference @@ -176,7 +176,7 @@ void ReviewDialog::setAttribute(ESM::Attribute::AttributeID attributeId, const M void ReviewDialog::setSkillValue(ESM::Skill::SkillEnum skillId, const MWMechanics::Stat& value) { skillValues[skillId] = value; - MyGUI::StaticTextPtr widget = skillWidgetMap[skillId]; + MyGUI::TextBox* widget = skillWidgetMap[skillId]; if (widget) { float modified = value.getModified(), base = value.getBase(); @@ -210,7 +210,7 @@ void ReviewDialog::configureSkills(const std::vector& major, const std::vec } } -void ReviewDialog::setStyledText(MyGUI::StaticTextPtr widget, ColorStyle style, const std::string &value) +void ReviewDialog::setStyledText(MyGUI::TextBox* widget, ColorStyle style, const std::string &value) { widget->setCaption(value); if (style == CS_Super) @@ -223,7 +223,7 @@ void ReviewDialog::setStyledText(MyGUI::StaticTextPtr widget, ColorStyle style, void ReviewDialog::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); + MyGUI::ImageBox* 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(); @@ -232,7 +232,7 @@ void ReviewDialog::addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2 void ReviewDialog::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); + MyGUI::TextBox* 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); @@ -240,14 +240,15 @@ void ReviewDialog::addGroup(const std::string &label, MyGUI::IntCoord &coord1, M coord2.top += lineHeight; } -MyGUI::StaticTextPtr ReviewDialog::addValueItem(const std::string text, const std::string &value, ColorStyle style, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) +MyGUI::TextBox* ReviewDialog::addValueItem(const std::string text, const std::string &value, ColorStyle style, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) { - MyGUI::StaticTextPtr skillNameWidget, skillValueWidget; + MyGUI::TextBox* skillNameWidget; + MyGUI::TextBox* skillValueWidget; - skillNameWidget = skillClientWidget->createWidget("SandText", coord1, MyGUI::Align::Default); + skillNameWidget = skillClientWidget->createWidget("SandText", coord1, MyGUI::Align::Default); skillNameWidget->setCaption(text); - skillValueWidget = skillClientWidget->createWidget("SandTextRight", coord2, MyGUI::Align::Default); + skillValueWidget = skillClientWidget->createWidget("SandTextRight", coord2, MyGUI::Align::Default); setStyledText(skillValueWidget, style, value); skillWidgets.push_back(skillNameWidget); @@ -261,9 +262,9 @@ MyGUI::StaticTextPtr ReviewDialog::addValueItem(const std::string text, const st void ReviewDialog::addItem(const std::string text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) { - MyGUI::StaticTextPtr skillNameWidget; + MyGUI::TextBox* skillNameWidget; - skillNameWidget = skillClientWidget->createWidget("SandText", coord1 + MyGUI::IntSize(coord2.width, 0), MyGUI::Align::Default); + skillNameWidget = skillClientWidget->createWidget("SandText", coord1 + MyGUI::IntSize(coord2.width, 0), MyGUI::Align::Default); skillNameWidget->setCaption(text); skillWidgets.push_back(skillNameWidget); @@ -299,7 +300,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(mWindowManager.getGameSettingString(skillNameId, skillNameId), boost::lexical_cast(static_cast(modified)), style, coord1, coord2); + MyGUI::TextBox* widget = addValueItem(mWindowManager.getGameSettingString(skillNameId, skillNameId), boost::lexical_cast(static_cast(modified)), style, coord1, coord2); skillWidgetMap[skillId] = widget; } } diff --git a/apps/openmw/mwgui/review.hpp b/apps/openmw/mwgui/review.hpp index 5846804f7..588c1b6b5 100644 --- a/apps/openmw/mwgui/review.hpp +++ b/apps/openmw/mwgui/review.hpp @@ -49,8 +49,8 @@ namespace MWGui void open(); // Events - typedef delegates::CDelegate0 EventHandle_Void; - typedef delegates::CDelegate1 EventHandle_Int; + typedef delegates::CMultiDelegate0 EventHandle_Void; + typedef delegates::CMultiDelegate1 EventHandle_Int; /** Event : Back button clicked.\n signature : void method()\n @@ -75,23 +75,23 @@ namespace MWGui CS_Normal, CS_Super }; - void setStyledText(MyGUI::StaticTextPtr widget, ColorStyle style, const std::string &value); + void setStyledText(MyGUI::TextBox* 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); + MyGUI::TextBox* 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 updateSkillArea(); - void onScrollChangePosition(MyGUI::VScrollPtr scroller, size_t pos); + void onScrollChangePosition(MyGUI::ScrollBar* scroller, size_t pos); void onWindowResize(MyGUI::Window* window); static const int lineHeight; - MyGUI::StaticTextPtr nameWidget, raceWidget, classWidget, birthSignWidget; + MyGUI::TextBox *nameWidget, *raceWidget, *classWidget, *birthSignWidget; MyGUI::WidgetPtr skillAreaWidget, skillClientWidget; - MyGUI::VScrollPtr skillScrollerWidget; + MyGUI::ScrollBar* skillScrollerWidget; int lastPos, clientHeight; Widgets::MWDynamicStatPtr health, magicka, fatigue; @@ -100,7 +100,7 @@ namespace MWGui SkillList majorSkills, minorSkills, miscSkills; std::map > skillValues; - std::map skillWidgetMap; + std::map skillWidgetMap; std::string name, raceId, birthSignId; ESM::Class klass; std::vector skillWidgets; //< Skills and other information diff --git a/apps/openmw/mwgui/stats_window.cpp b/apps/openmw/mwgui/stats_window.cpp index 30a4015e3..675e5141f 100644 --- a/apps/openmw/mwgui/stats_window.cpp +++ b/apps/openmw/mwgui/stats_window.cpp @@ -12,10 +12,23 @@ using namespace MWGui; const int StatsWindow::lineHeight = 18; StatsWindow::StatsWindow (WindowManager& parWindowManager) - : WindowBase("openmw_stats_window_layout.xml", parWindowManager) + : WindowPinnableBase("openmw_stats_window_layout.xml", parWindowManager) + , skillAreaWidget(NULL) + , skillClientWidget(NULL) + , skillScrollerWidget(NULL) , lastPos(0) + , clientHeight(0) + , majorSkills() + , minorSkills() + , miscSkills() + , skillValues() + , skillWidgetMap() + , factionWidgetMap() + , factions() + , birthSignId() , reputation(0) , bounty(0) + , skillWidgets() { setCoord(0,0,498, 342); @@ -48,20 +61,20 @@ StatsWindow::StatsWindow (WindowManager& parWindowManager) getWidget(skillClientWidget, "SkillClient"); getWidget(skillScrollerWidget, "SkillScroller"); - skillScrollerWidget->eventScrollChangePosition = MyGUI::newDelegate(this, &StatsWindow::onScrollChangePosition); + 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)); + skillWidgetMap.insert(std::pair(i, nullptr)); } MyGUI::WindowPtr t = static_cast(mMainWidget); - t->eventWindowChangeCoord = MyGUI::newDelegate(this, &StatsWindow::onWindowResize); + t->eventWindowChangeCoord += MyGUI::newDelegate(this, &StatsWindow::onWindowResize); } -void StatsWindow::onScrollChangePosition(MyGUI::VScrollPtr scroller, size_t pos) +void StatsWindow::onScrollChangePosition(MyGUI::ScrollBar* scroller, size_t pos) { int diff = lastPos - pos; // Adjust position of all widget according to difference @@ -95,10 +108,10 @@ void StatsWindow::setBar(const std::string& name, const std::string& tname, int void StatsWindow::setPlayerName(const std::string& playerName) { - mMainWidget->setCaption(playerName); + static_cast(mMainWidget)->setCaption(playerName); } -void StatsWindow::setStyledText(MyGUI::StaticTextPtr widget, ColorStyle style, const std::string &value) +void StatsWindow::setStyledText(MyGUI::TextBox* widget, ColorStyle style, const std::string &value) { widget->setCaption(value); if (style == CS_Super) @@ -175,7 +188,7 @@ void StatsWindow::setValue (const std::string& id, int value) void StatsWindow::setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::Stat& value) { skillValues[parSkill] = value; - MyGUI::StaticTextPtr widget = skillWidgetMap[(int)parSkill]; + MyGUI::TextBox* widget = skillWidgetMap[(int)parSkill]; if (widget) { float modified = value.getModified(), base = value.getBase(); @@ -221,7 +234,7 @@ void StatsWindow::setBirthSign (const std::string& 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); + MyGUI::ImageBox* 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(); @@ -230,7 +243,7 @@ void StatsWindow::addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) 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); + MyGUI::TextBox* 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); @@ -238,14 +251,14 @@ void StatsWindow::addGroup(const std::string &label, MyGUI::IntCoord &coord1, My coord2.top += lineHeight; } -MyGUI::StaticTextPtr StatsWindow::addValueItem(const std::string text, const std::string &value, ColorStyle style, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) +MyGUI::TextBox* StatsWindow::addValueItem(const std::string text, const std::string &value, ColorStyle style, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) { - MyGUI::StaticTextPtr skillNameWidget, skillValueWidget; + MyGUI::TextBox *skillNameWidget, *skillValueWidget; - skillNameWidget = skillClientWidget->createWidget("SandText", coord1, MyGUI::Align::Default); + skillNameWidget = skillClientWidget->createWidget("SandText", coord1, MyGUI::Align::Default); skillNameWidget->setCaption(text); - skillValueWidget = skillClientWidget->createWidget("SandTextRight", coord2, MyGUI::Align::Default); + skillValueWidget = skillClientWidget->createWidget("SandTextRight", coord2, MyGUI::Align::Default); setStyledText(skillValueWidget, style, value); skillWidgets.push_back(skillNameWidget); @@ -259,9 +272,9 @@ MyGUI::StaticTextPtr StatsWindow::addValueItem(const std::string text, const std void StatsWindow::addItem(const std::string text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) { - MyGUI::StaticTextPtr skillNameWidget; + MyGUI::TextBox* skillNameWidget; - skillNameWidget = skillClientWidget->createWidget("SandText", coord1 + MyGUI::IntSize(coord2.width, 0), MyGUI::Align::Default); + skillNameWidget = skillClientWidget->createWidget("SandText", coord1 + MyGUI::IntSize(coord2.width, 0), MyGUI::Align::Default); skillNameWidget->setCaption(text); skillWidgets.push_back(skillNameWidget); @@ -297,7 +310,7 @@ void StatsWindow::addSkills(const SkillList &skills, const std::string &titleId, 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); + MyGUI::TextBox* widget = addValueItem(mWindowManager.getGameSettingString(skillNameId, skillNameId), boost::lexical_cast(static_cast(modified)), style, coord1, coord2); skillWidgetMap[skillId] = widget; } } @@ -368,3 +381,8 @@ void StatsWindow::updateScroller() skillScrollerWidget->setScrollRange(std::max(clientHeight - skillClientWidget->getHeight(), 0)); skillScrollerWidget->setScrollPage(std::max(skillClientWidget->getHeight() - lineHeight, 0)); } + +void StatsWindow::onPinToggled() +{ + mWindowManager.setHMSVisibility(!mPinned); +} diff --git a/apps/openmw/mwgui/stats_window.hpp b/apps/openmw/mwgui/stats_window.hpp index 9db5c240b..f2731e545 100644 --- a/apps/openmw/mwgui/stats_window.hpp +++ b/apps/openmw/mwgui/stats_window.hpp @@ -9,13 +9,13 @@ #include #include "../mwmechanics/stat.hpp" -#include "window_base.hpp" +#include "window_pinnable_base.hpp" namespace MWGui { class WindowManager; - class StatsWindow : public WindowBase + class StatsWindow : public WindowPinnableBase { public: typedef std::pair Faction; @@ -49,31 +49,34 @@ namespace MWGui CS_Normal, CS_Super }; - void setStyledText(MyGUI::StaticTextPtr widget, ColorStyle style, const std::string &value); + void setStyledText(MyGUI::TextBox* 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); + MyGUI::TextBox* 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 onScrollChangePosition(MyGUI::ScrollBar* scroller, size_t pos); void onWindowResize(MyGUI::Window* window); static const int lineHeight; MyGUI::WidgetPtr skillAreaWidget, skillClientWidget; - MyGUI::VScrollPtr skillScrollerWidget; + MyGUI::ScrollBar* skillScrollerWidget; int lastPos, clientHeight; SkillList majorSkills, minorSkills, miscSkills; std::map > skillValues; - std::map skillWidgetMap; + 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 + + protected: + virtual void onPinToggled(); }; } #endif diff --git a/apps/openmw/mwgui/text_input.cpp b/apps/openmw/mwgui/text_input.cpp index 83ebef657..8ac07e766 100644 --- a/apps/openmw/mwgui/text_input.cpp +++ b/apps/openmw/mwgui/text_input.cpp @@ -10,12 +10,12 @@ TextInputDialog::TextInputDialog(WindowManager& parWindowManager) center(); getWidget(textEdit, "TextEdit"); - textEdit->eventEditSelectAccept = newDelegate(this, &TextInputDialog::onTextAccepted); + textEdit->eventEditSelectAccept += newDelegate(this, &TextInputDialog::onTextAccepted); // TODO: These buttons should be managed by a Dialog class MyGUI::ButtonPtr okButton; getWidget(okButton, "OKButton"); - okButton->eventMouseButtonClick = MyGUI::newDelegate(this, &TextInputDialog::onOkClicked); + okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TextInputDialog::onOkClicked); // Make sure the edit box has focus MyGUI::InputManager::getInstance().setKeyFocusWidget(textEdit); diff --git a/apps/openmw/mwgui/widgets.cpp b/apps/openmw/mwgui/widgets.cpp index f62da2bab..74603aaf1 100644 --- a/apps/openmw/mwgui/widgets.cpp +++ b/apps/openmw/mwgui/widgets.cpp @@ -62,24 +62,24 @@ void MWSkill::updateWidgets() { if (skillId == ESM::Skill::Length) { - skillNameWidget->setCaption(""); + static_cast(skillNameWidget)->setCaption(""); } else { const std::string &name = manager->getGameSettingString(ESM::Skill::sSkillNameIds[skillId], ""); - skillNameWidget->setCaption(name); + static_cast(skillNameWidget)->setCaption(name); } } if (skillValueWidget) { SkillValue::Type modified = value.getModified(), base = value.getBase(); - skillValueWidget->setCaption(boost::lexical_cast(modified)); + static_cast(skillValueWidget)->setCaption(boost::lexical_cast(modified)); if (modified > base) - skillValueWidget->setState("increased"); + skillValueWidget->_setWidgetState("increased"); else if (modified < base) - skillValueWidget->setState("decreased"); + skillValueWidget->_setWidgetState("decreased"); else - skillValueWidget->setState("normal"); + skillValueWidget->_setWidgetState("normal"); } } @@ -88,59 +88,32 @@ void MWSkill::onClicked(MyGUI::Widget* _sender) eventClicked(this); } -void MWSkill::_initialise(WidgetStyle _style, const IntCoord& _coord, Align _align, ResourceSkin* _info, Widget* _parent, ICroppedRectangle * _croppedParent, IWidgetCreator * _creator, const std::string& _name) -{ - Base::_initialise(_style, _coord, _align, _info, _parent, _croppedParent, _creator, _name); - - initialiseWidgetSkin(_info); -} - MWSkill::~MWSkill() { - shutdownWidgetSkin(); } -void MWSkill::baseChangeWidgetSkin(ResourceSkin* _info) +void MWSkill::initialiseOverride() { - shutdownWidgetSkin(); - Base::baseChangeWidgetSkin(_info); - initialiseWidgetSkin(_info); -} + Base::initialiseOverride(); -void MWSkill::initialiseWidgetSkin(ResourceSkin* _info) -{ - for (VectorWidgetPtr::iterator iter=mWidgetChildSkin.begin(); iter!=mWidgetChildSkin.end(); ++iter) + assignWidget(skillNameWidget, "StatName"); + assignWidget(skillValueWidget, "StatValue"); + + MyGUI::ButtonPtr button; + assignWidget(button, "StatNameButton"); + if (button) { - const std::string &name = *(*iter)->_getInternalData(); - if (name == "StatName") - { - MYGUI_DEBUG_ASSERT( ! skillNameWidget, "widget already assigned"); - skillNameWidget = (*iter)->castType(); - } - else if (name == "StatValue") - { - MYGUI_DEBUG_ASSERT( ! skillValueWidget, "widget already assigned"); - skillValueWidget = (*iter)->castType(); - } - else if (name == "StatNameButton") - { - MYGUI_DEBUG_ASSERT( ! skillNameWidget, "widget already assigned"); - MyGUI::ButtonPtr button = (*iter)->castType