mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-25 15:35:23 +00:00
Merge branch 'master' into ref
This commit is contained in:
commit
4986b7d65d
@ -14,9 +14,8 @@ before_install:
|
||||
- sudo apt-get install -qq libboost-all-dev libgtest-dev google-mock libzzip-dev
|
||||
- sudo apt-get install -qq libqt4-dev libxaw7-dev libxrandr-dev libfreeimage-dev libpng-dev
|
||||
- sudo apt-get install -qq libopenal-dev libmpg123-dev libsndfile1-dev
|
||||
- sudo apt-get install -qq libcg nvidia-cg-toolkit
|
||||
- sudo apt-get install -qq libavcodec-dev libavformat-dev libavdevice-dev libavutil-dev libswscale-dev libpostproc-dev
|
||||
- sudo apt-get install -qq libois-dev libbullet-dev libogre-static-dev libmygui-static-dev
|
||||
- sudo apt-get install -qq libbullet-dev libogre-static-dev libmygui-static-dev libsdl2-static-dev
|
||||
- sudo mkdir /usr/src/gtest/build
|
||||
- cd /usr/src/gtest/build
|
||||
- sudo cmake .. -DBUILD_SHARED_LIBS=1
|
||||
@ -27,7 +26,7 @@ before_script:
|
||||
- cd -
|
||||
- mkdir build
|
||||
- cd build
|
||||
- cmake .. -DOGRE_STATIC=1 -DMYGUI_STATIC=1 -DBUILD_WITH_CODE_COVERAGE=1 -DBUILD_UNITTESTS=1
|
||||
- cmake .. -DOGRE_STATIC=1 -DMYGUI_STATIC=1 -DBOOST_STATIC=1 -DSDL2_STATIC=1 -DBUILD_WITH_CODE_COVERAGE=1 -DBUILD_UNITTESTS=1
|
||||
script:
|
||||
- make -j4
|
||||
after_script:
|
||||
|
@ -4,6 +4,10 @@ if (APPLE)
|
||||
set(APP_BUNDLE_NAME "${CMAKE_PROJECT_NAME}.app")
|
||||
|
||||
set(APP_BUNDLE_DIR "${OpenMW_BINARY_DIR}/${APP_BUNDLE_NAME}")
|
||||
|
||||
set(CMAKE_EXE_LINKER_FLAGS "-F /Library/Frameworks")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "-F /Library/Frameworks")
|
||||
set(CMAKE_MODULE_LINKER_FLAGS "-F /Library/Frameworks")
|
||||
endif (APPLE)
|
||||
|
||||
# Macros
|
||||
@ -15,7 +19,7 @@ include (OpenMWMacros)
|
||||
# Version
|
||||
|
||||
set (OPENMW_VERSION_MAJOR 0)
|
||||
set (OPENMW_VERSION_MINOR 23)
|
||||
set (OPENMW_VERSION_MINOR 24)
|
||||
set (OPENMW_VERSION_RELEASE 0)
|
||||
|
||||
set (OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VERSION_RELEASE}")
|
||||
@ -27,6 +31,7 @@ configure_file ("${OpenMW_SOURCE_DIR}/Docs/mainpage.hpp.cmake" "${OpenMW_SOURCE_
|
||||
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)
|
||||
option(BOOST_STATIC "Link static build of Boost into the binaries" FALSE)
|
||||
option(SDL2_STATIC "Link static build of SDL into the binaries" FALSE)
|
||||
|
||||
# Apps and tools
|
||||
option(BUILD_BSATOOL "build BSA extractor" OFF)
|
||||
@ -77,7 +82,13 @@ set(OENGINE_OGRE
|
||||
${LIBDIR}/openengine/ogre/fader.cpp
|
||||
${LIBDIR}/openengine/ogre/particles.cpp
|
||||
${LIBDIR}/openengine/ogre/selectionbuffer.cpp
|
||||
${LIBDIR}/openengine/ogre/imagerotate.cpp
|
||||
)
|
||||
|
||||
if (APPLE)
|
||||
set(OENGINE_OGRE ${OENGINE_OGRE} ${LIBDIR}/openengine/ogre/osx_utils.mm)
|
||||
endif ()
|
||||
|
||||
set(OENGINE_GUI
|
||||
${LIBDIR}/openengine/gui/manager.cpp
|
||||
)
|
||||
@ -181,6 +192,12 @@ if (UNIX AND NOT APPLE)
|
||||
find_package (Threads)
|
||||
endif()
|
||||
|
||||
include (CheckIncludeFileCXX)
|
||||
check_include_file_cxx(unordered_map HAVE_UNORDERED_MAP)
|
||||
if (HAVE_UNORDERED_MAP)
|
||||
add_definitions(-DHAVE_UNORDERED_MAP)
|
||||
endif ()
|
||||
|
||||
|
||||
set(BOOST_COMPONENTS system filesystem program_options thread date_time wave)
|
||||
|
||||
@ -191,7 +208,7 @@ endif()
|
||||
find_package(OGRE REQUIRED)
|
||||
find_package(MyGUI REQUIRED)
|
||||
find_package(Boost REQUIRED COMPONENTS ${BOOST_COMPONENTS})
|
||||
find_package(OIS REQUIRED)
|
||||
find_package(SDL2 REQUIRED)
|
||||
find_package(OpenAL REQUIRED)
|
||||
find_package(Bullet REQUIRED)
|
||||
IF(OGRE_STATIC)
|
||||
@ -205,7 +222,8 @@ 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}
|
||||
${SDL2_INCLUDE_DIR}
|
||||
${Boost_INCLUDE_DIR}
|
||||
${PLATFORM_INCLUDE_DIR}
|
||||
${MYGUI_INCLUDE_DIRS}
|
||||
${MYGUI_PLATFORM_INCLUDE_DIRS}
|
||||
@ -214,7 +232,7 @@ include_directories("."
|
||||
${LIBDIR}
|
||||
)
|
||||
|
||||
link_directories(${Boost_LIBRARY_DIRS} ${OGRE_LIB_DIR} ${MYGUI_LIB_DIR})
|
||||
link_directories(${SDL2_LIBRARY_DIRS} ${Boost_LIBRARY_DIRS} ${OGRE_LIB_DIR} ${MYGUI_LIB_DIR})
|
||||
|
||||
if (APPLE)
|
||||
# List used Ogre plugins
|
||||
@ -287,9 +305,12 @@ configure_file(${OpenMW_SOURCE_DIR}/files/transparency-overrides.cfg
|
||||
|
||||
configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg.local
|
||||
"${OpenMW_BINARY_DIR}/openmw.cfg")
|
||||
|
||||
configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg
|
||||
"${OpenMW_BINARY_DIR}/openmw.cfg.install")
|
||||
|
||||
configure_file(${OpenMW_SOURCE_DIR}/files/opencs.cfg
|
||||
"${OpenMW_BINARY_DIR}/opencs.cfg")
|
||||
|
||||
if (NOT WIN32 AND NOT APPLE)
|
||||
configure_file(${OpenMW_SOURCE_DIR}/files/openmw.desktop
|
||||
@ -300,15 +321,15 @@ endif()
|
||||
|
||||
# Compiler settings
|
||||
if (CMAKE_COMPILER_IS_GNUCC)
|
||||
add_definitions (-Wall -Wextra -Wno-unused-parameter -Wno-reorder -std=c++98 -pedantic -Wno-long-long)
|
||||
SET(CMAKE_CXX_FLAGS "-Wall -Wextra -Wno-unused-parameter -Wno-reorder -std=c++98 -pedantic -Wno-long-long ${CMAKE_CXX_FLAGS}")
|
||||
|
||||
# Silence warnings in OGRE headers. Remove once OGRE got fixed!
|
||||
add_definitions (-Wno-ignored-qualifiers)
|
||||
SET(CMAKE_CXX_FLAGS "-Wno-ignored-qualifiers ${CMAKE_CXX_FLAGS}")
|
||||
|
||||
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)
|
||||
SET(CMAKE_CXX_FLAGS "-Wno-unused-but-set-parameter ${CMAKE_CXX_FLAGS}")
|
||||
endif("${GCC_VERSION}" VERSION_GREATER 4.6 OR "${GCC_VERSION}" VERSION_EQUAL 4.6)
|
||||
endif (CMAKE_COMPILER_IS_GNUCC)
|
||||
|
||||
@ -334,6 +355,7 @@ if(DPKG_PROGRAM)
|
||||
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}/transparency-overrides.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}/opencs.cfg" DESTINATION "../etc/openmw/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw")
|
||||
|
||||
#Install resources
|
||||
INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION "share/games/openmw/" FILE_PERMISSIONS OWNER_READ GROUP_READ WORLD_READ COMPONENT "Resources")
|
||||
@ -349,8 +371,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 bsatool;Bsatool esmtool;Esmtool omwlauncher;OMWLauncher mwiniimporter;MWiniImporter")
|
||||
SET(CPACK_DEBIAN_PACKAGE_DEPENDS "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 bsatool;Bsatool esmtool;Esmtool omwlauncher;OMWLauncher mwiniimporter;MWiniImporter")
|
||||
SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.11.2), libfreetype6 (>= 2.2.1), libgcc1 (>= 1:4.1.1), libmpg123-0 (>= 1.12.1), 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")
|
||||
|
||||
@ -437,6 +459,7 @@ endif(WIN32)
|
||||
# Extern
|
||||
add_subdirectory (extern/shiny)
|
||||
add_subdirectory (extern/oics)
|
||||
add_subdirectory (extern/sdl4ogre)
|
||||
|
||||
# Components
|
||||
add_subdirectory (components)
|
||||
@ -572,6 +595,7 @@ if (APPLE)
|
||||
install(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" RENAME "openmw.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
||||
install(FILES "${OpenMW_BINARY_DIR}/settings-default.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
||||
install(FILES "${OpenMW_BINARY_DIR}/transparency-overrides.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
||||
install(FILES "${OpenMW_BINARY_DIR}/opencs.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
||||
|
||||
set(CPACK_GENERATOR "DragNDrop")
|
||||
set(CPACK_PACKAGE_VERSION ${OPENMW_VERSION})
|
||||
@ -687,6 +711,7 @@ if (NOT WIN32 AND NOT DPKG_PROGRAM AND NOT APPLE)
|
||||
#INSTALL(FILES "${OpenMW_BINARY_DIR}/plugins.cfg" DESTINATION "${SYSCONFDIR}" )
|
||||
INSTALL(FILES "${OpenMW_BINARY_DIR}/settings-default.cfg" DESTINATION "${SYSCONFDIR}" )
|
||||
INSTALL(FILES "${OpenMW_BINARY_DIR}/transparency-overrides.cfg" DESTINATION "${SYSCONFDIR}" )
|
||||
INSTALL(FILES "${OpenMW_BINARY_DIR}/opencs.cfg" DESTINATION "${SYSCONFDIR}" )
|
||||
|
||||
# Install resources
|
||||
INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION "${DATADIR}" )
|
||||
|
@ -17,11 +17,6 @@ target_link_libraries(esmtool
|
||||
components
|
||||
)
|
||||
|
||||
#if (APPLE)
|
||||
# find_library(CARBON_FRAMEWORK Carbon)
|
||||
# target_link_libraries(openmw ${CARBON_FRAMEWORK})
|
||||
#endif (APPLE)
|
||||
|
||||
if (BUILD_WITH_CODE_COVERAGE)
|
||||
add_definitions (--coverage)
|
||||
target_link_libraries(esmtool gcov)
|
||||
|
@ -108,11 +108,26 @@ bool parseOptions (int argc, char** argv, Arguments &info)
|
||||
// there might be a better way to do this
|
||||
bpo::options_description all;
|
||||
all.add(desc).add(hidden);
|
||||
bpo::parsed_options valid_opts = bpo::command_line_parser(argc, argv)
|
||||
.options(all).positional(p).run();
|
||||
|
||||
bpo::variables_map variables;
|
||||
bpo::store(valid_opts, variables);
|
||||
|
||||
try
|
||||
{
|
||||
bpo::parsed_options valid_opts = bpo::command_line_parser(argc, argv)
|
||||
.options(all).positional(p).run();
|
||||
|
||||
bpo::store(valid_opts, variables);
|
||||
}
|
||||
catch(boost::program_options::unknown_option & x)
|
||||
{
|
||||
std::cerr << "ERROR: " << x.what() << std::endl;
|
||||
return false;
|
||||
}
|
||||
catch(boost::program_options::invalid_command_line_syntax & x)
|
||||
{
|
||||
std::cerr << "ERROR: " << x.what() << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
bpo::notify(variables);
|
||||
|
||||
if (variables.count ("help"))
|
||||
|
@ -90,6 +90,7 @@ target_link_libraries(omwlauncher
|
||||
${Boost_LIBRARIES}
|
||||
${OGRE_LIBRARIES}
|
||||
${OGRE_STATIC_PLUGINS}
|
||||
${SDL2_LIBRARY}
|
||||
${QT_LIBRARIES}
|
||||
components
|
||||
)
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <QDesktopWidget>
|
||||
#include <QMessageBox>
|
||||
#include <QDir>
|
||||
#include <SDL.h>
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
@ -35,13 +36,14 @@ GraphicsPage::GraphicsPage(Files::ConfigurationManager &cfg, GraphicsSettings &g
|
||||
setupUi(this);
|
||||
|
||||
// Set the maximum res we can set in windowed mode
|
||||
QRect res = QApplication::desktop()->screenGeometry();
|
||||
QRect res = getMaximumResolution();
|
||||
customWidthSpinBox->setMaximum(res.width());
|
||||
customHeightSpinBox->setMaximum(res.height());
|
||||
|
||||
connect(rendererComboBox, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(rendererChanged(const QString&)));
|
||||
connect(fullScreenCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotFullScreenChanged(int)));
|
||||
connect(standardRadioButton, SIGNAL(toggled(bool)), this, SLOT(slotStandardToggled(bool)));
|
||||
connect(screenComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(screenChanged(int)));
|
||||
|
||||
}
|
||||
|
||||
@ -144,17 +146,41 @@ bool GraphicsPage::setupOgre()
|
||||
}
|
||||
|
||||
antiAliasingComboBox->clear();
|
||||
resolutionComboBox->clear();
|
||||
antiAliasingComboBox->addItems(getAvailableOptions(QString("FSAA"), mSelectedRenderSystem));
|
||||
resolutionComboBox->addItems(getAvailableResolutions(mSelectedRenderSystem));
|
||||
|
||||
// Load the rest of the values
|
||||
loadSettings();
|
||||
return true;
|
||||
}
|
||||
|
||||
void GraphicsPage::loadSettings()
|
||||
bool GraphicsPage::setupSDL()
|
||||
{
|
||||
int displays = SDL_GetNumVideoDisplays();
|
||||
|
||||
if (displays < 0)
|
||||
{
|
||||
QMessageBox msgBox;
|
||||
msgBox.setWindowTitle(tr("Error receiving number of screens"));
|
||||
msgBox.setIcon(QMessageBox::Critical);
|
||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||
msgBox.setText(tr("<br><b>SDL_GetNumDisplayModes failed:</b><br><br>") + QString::fromStdString(SDL_GetError()) + "<br>");
|
||||
msgBox.exec();
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < displays; i++)
|
||||
{
|
||||
screenComboBox->addItem(QString(tr("Screen ")) + QString::number(i + 1));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GraphicsPage::loadSettings()
|
||||
{
|
||||
if (!setupSDL())
|
||||
return false;
|
||||
if (!setupOgre())
|
||||
return false;
|
||||
|
||||
if (mGraphicsSettings.value(QString("Video/vsync")) == QLatin1String("true"))
|
||||
vSyncCheckBox->setCheckState(Qt::Checked);
|
||||
|
||||
@ -168,6 +194,9 @@ void GraphicsPage::loadSettings()
|
||||
QString width = mGraphicsSettings.value(QString("Video/resolution x"));
|
||||
QString height = mGraphicsSettings.value(QString("Video/resolution y"));
|
||||
QString resolution = width + QString(" x ") + height;
|
||||
QString screen = mGraphicsSettings.value(QString("Video/screen"));
|
||||
|
||||
screenComboBox->setCurrentIndex(screen.toInt());
|
||||
|
||||
int resIndex = resolutionComboBox->findText(resolution, Qt::MatchStartsWith);
|
||||
|
||||
@ -180,6 +209,8 @@ void GraphicsPage::loadSettings()
|
||||
customHeightSpinBox->setValue(height.toInt());
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GraphicsPage::saveSettings()
|
||||
@ -205,6 +236,8 @@ void GraphicsPage::saveSettings()
|
||||
mGraphicsSettings.setValue(QString("Video/resolution x"), QString::number(customWidthSpinBox->value()));
|
||||
mGraphicsSettings.setValue(QString("Video/resolution y"), QString::number(customHeightSpinBox->value()));
|
||||
}
|
||||
|
||||
mGraphicsSettings.setValue(QString("Video/screen"), QString::number(screenComboBox->currentIndex()));
|
||||
}
|
||||
|
||||
QStringList GraphicsPage::getAvailableOptions(const QString &key, Ogre::RenderSystem *renderer)
|
||||
@ -240,64 +273,83 @@ QStringList GraphicsPage::getAvailableOptions(const QString &key, Ogre::RenderSy
|
||||
return result;
|
||||
}
|
||||
|
||||
QStringList GraphicsPage::getAvailableResolutions(Ogre::RenderSystem *renderer)
|
||||
QStringList GraphicsPage::getAvailableResolutions(int screen)
|
||||
{
|
||||
QString key("Video Mode");
|
||||
QStringList result;
|
||||
SDL_DisplayMode mode;
|
||||
int modeIndex, modes = SDL_GetNumDisplayModes(screen);
|
||||
|
||||
uint row = 0;
|
||||
Ogre::ConfigOptionMap options = renderer->getConfigOptions();
|
||||
|
||||
for (Ogre::ConfigOptionMap::iterator i = options.begin (); i != options.end (); i++, row++)
|
||||
if (modes < 0)
|
||||
{
|
||||
if (key.toStdString() != i->first)
|
||||
continue;
|
||||
|
||||
Ogre::StringVector::iterator opt_it;
|
||||
uint idx = 0;
|
||||
|
||||
for (opt_it = i->second.possibleValues.begin ();
|
||||
opt_it != i->second.possibleValues.end (); opt_it++, idx++)
|
||||
{
|
||||
QRegExp resolutionRe(QString("(\\d+) x (\\d+).*"));
|
||||
QString resolution = QString::fromStdString(*opt_it).simplified();
|
||||
|
||||
if (resolutionRe.exactMatch(resolution)) {
|
||||
|
||||
int width = resolutionRe.cap(1).toInt();
|
||||
int height = resolutionRe.cap(2).toInt();
|
||||
|
||||
QString aspect = getAspect(width, height);
|
||||
QString cleanRes = resolutionRe.cap(1) + QString(" x ") + resolutionRe.cap(2);
|
||||
|
||||
if (aspect == QLatin1String("16:9") || aspect == QLatin1String("16:10")) {
|
||||
cleanRes.append(tr("\t(Wide ") + aspect + ")");
|
||||
|
||||
} else if (aspect == QLatin1String("4:3")) {
|
||||
cleanRes.append(tr("\t(Standard 4:3)"));
|
||||
}
|
||||
// do not add duplicate resolutions
|
||||
if (!result.contains(cleanRes))
|
||||
result.append(cleanRes);
|
||||
}
|
||||
}
|
||||
QMessageBox msgBox;
|
||||
msgBox.setWindowTitle(tr("Error receiving resolutions"));
|
||||
msgBox.setIcon(QMessageBox::Critical);
|
||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||
msgBox.setText(tr("<br><b>SDL_GetNumDisplayModes failed:</b><br><br>") + QString::fromStdString(SDL_GetError()) + "<br>");
|
||||
msgBox.exec();
|
||||
return result;
|
||||
}
|
||||
|
||||
// Sort the resolutions in descending order
|
||||
qSort(result.begin(), result.end(), naturalSortGreaterThanCI);
|
||||
for (modeIndex = 0; modeIndex < modes; modeIndex++)
|
||||
{
|
||||
if (SDL_GetDisplayMode(screen, modeIndex, &mode) < 0)
|
||||
{
|
||||
QMessageBox msgBox;
|
||||
msgBox.setWindowTitle(tr("Error receiving resolutions"));
|
||||
msgBox.setIcon(QMessageBox::Critical);
|
||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||
msgBox.setText(tr("<br><b>SDL_GetDisplayMode failed:</b><br><br>") + QString::fromStdString(SDL_GetError()) + "<br>");
|
||||
msgBox.exec();
|
||||
return result;
|
||||
}
|
||||
|
||||
QString aspect = getAspect(mode.w, mode.h);
|
||||
QString resolution = QString::number(mode.w) + QString(" x ") + QString::number(mode.h);
|
||||
|
||||
if (aspect == QLatin1String("16:9") || aspect == QLatin1String("16:10")) {
|
||||
resolution.append(tr("\t(Wide ") + aspect + ")");
|
||||
|
||||
} else if (aspect == QLatin1String("4:3")) {
|
||||
resolution.append(tr("\t(Standard 4:3)"));
|
||||
}
|
||||
|
||||
result.append(resolution);
|
||||
}
|
||||
|
||||
result.removeDuplicates();
|
||||
return result;
|
||||
}
|
||||
|
||||
QRect GraphicsPage::getMaximumResolution()
|
||||
{
|
||||
QRect max;
|
||||
int screens = QApplication::desktop()->screenCount();
|
||||
for (int i = 0; i < screens; ++i)
|
||||
{
|
||||
QRect res = QApplication::desktop()->screenGeometry(i);
|
||||
if (res.width() > max.width())
|
||||
max.setWidth(res.width());
|
||||
if (res.height() > max.height())
|
||||
max.setHeight(res.height());
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
void GraphicsPage::rendererChanged(const QString &renderer)
|
||||
{
|
||||
mSelectedRenderSystem = mOgre->getRenderSystemByName(renderer.toStdString());
|
||||
|
||||
antiAliasingComboBox->clear();
|
||||
resolutionComboBox->clear();
|
||||
|
||||
antiAliasingComboBox->addItems(getAvailableOptions(QString("FSAA"), mSelectedRenderSystem));
|
||||
resolutionComboBox->addItems(getAvailableResolutions(mSelectedRenderSystem));
|
||||
}
|
||||
|
||||
void GraphicsPage::screenChanged(int screen)
|
||||
{
|
||||
if (screen >= 0) {
|
||||
resolutionComboBox->clear();
|
||||
resolutionComboBox->addItems(getAvailableResolutions(screen));
|
||||
}
|
||||
}
|
||||
|
||||
void GraphicsPage::slotFullScreenChanged(int state)
|
||||
|
@ -30,10 +30,11 @@ public:
|
||||
GraphicsPage(Files::ConfigurationManager &cfg, GraphicsSettings &graphicsSettings, QWidget *parent = 0);
|
||||
|
||||
void saveSettings();
|
||||
bool setupOgre();
|
||||
bool loadSettings();
|
||||
|
||||
public slots:
|
||||
void rendererChanged(const QString &renderer);
|
||||
void screenChanged(int screen);
|
||||
|
||||
private slots:
|
||||
void slotFullScreenChanged(int state);
|
||||
@ -55,10 +56,11 @@ private:
|
||||
GraphicsSettings &mGraphicsSettings;
|
||||
|
||||
QStringList getAvailableOptions(const QString &key, Ogre::RenderSystem *renderer);
|
||||
QStringList getAvailableResolutions(Ogre::RenderSystem *renderer);
|
||||
|
||||
void loadSettings();
|
||||
QStringList getAvailableResolutions(int screen);
|
||||
QRect getMaximumResolution();
|
||||
|
||||
bool setupOgre();
|
||||
bool setupSDL();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,11 +1,23 @@
|
||||
#include <QApplication>
|
||||
#include <QTextCodec>
|
||||
#include <QDir>
|
||||
#include <QDebug>
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
#include "maindialog.hpp"
|
||||
// SDL workaround
|
||||
#include "graphicspage.hpp"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
SDL_SetHint(SDL_HINT_RENDER_DRIVER, "software");
|
||||
if (SDL_Init(SDL_INIT_VIDEO) != 0)
|
||||
{
|
||||
qDebug() << "SDL_Init failed: " << QString::fromStdString(SDL_GetError());
|
||||
return 0;
|
||||
}
|
||||
|
||||
QApplication app(argc, argv);
|
||||
|
||||
// Now we make sure the current dir is set to application path
|
||||
@ -41,6 +53,8 @@ int main(int argc, char *argv[])
|
||||
return 0;
|
||||
}
|
||||
|
||||
return app.exec();
|
||||
int returnValue = app.exec();
|
||||
SDL_Quit();
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
|
@ -292,8 +292,8 @@ bool MainDialog::setup()
|
||||
// Now create the pages as they need the settings
|
||||
createPages();
|
||||
|
||||
// Call this so we can exit on Ogre errors before mainwindow is shown
|
||||
if (!mGraphicsPage->setupOgre())
|
||||
// Call this so we can exit on Ogre/SDL errors before mainwindow is shown
|
||||
if (!mGraphicsPage->loadSettings())
|
||||
return false;
|
||||
|
||||
loadSettings();
|
||||
@ -310,6 +310,8 @@ void MainDialog::changePage(QListWidgetItem *current, QListWidgetItem *previous)
|
||||
|
||||
bool MainDialog::setupLauncherSettings()
|
||||
{
|
||||
mLauncherSettings.setMultiValueEnabled(true);
|
||||
|
||||
QString userPath = QString::fromStdString(mCfgMgr.getUserPath().string());
|
||||
|
||||
QStringList paths;
|
||||
@ -427,6 +429,8 @@ bool MainDialog::setupGameSettings()
|
||||
|
||||
bool MainDialog::setupGraphicsSettings()
|
||||
{
|
||||
mGraphicsSettings.setMultiValueEnabled(false);
|
||||
|
||||
QString userPath = QString::fromStdString(mCfgMgr.getUserPath().string());
|
||||
QString globalPath = QString::fromStdString(mCfgMgr.getGlobalPath().string());
|
||||
|
||||
@ -608,8 +612,21 @@ void MainDialog::closeEvent(QCloseEvent *event)
|
||||
|
||||
void MainDialog::play()
|
||||
{
|
||||
if (!writeSettings())
|
||||
if (!writeSettings()) {
|
||||
qApp->quit();
|
||||
return;
|
||||
}
|
||||
|
||||
if(!mGameSettings.hasMaster()) {
|
||||
QMessageBox msgBox;
|
||||
msgBox.setWindowTitle(tr("No master file selected"));
|
||||
msgBox.setIcon(QMessageBox::Warning);
|
||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||
msgBox.setText(tr("<br><b>You do not have any master files selected.</b><br><br> \
|
||||
OpenMW will not start without a master file selected.<br>"));
|
||||
msgBox.exec();
|
||||
return;
|
||||
}
|
||||
|
||||
// Launch the game detached
|
||||
startProgram(QString("openmw"), true);
|
||||
|
@ -6,8 +6,6 @@
|
||||
#include <QRegExp>
|
||||
#include <QMap>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include <components/files/configurationmanager.hpp>
|
||||
|
||||
#include <boost/version.hpp>
|
||||
@ -103,8 +101,8 @@ bool GameSettings::readFile(QTextStream &stream)
|
||||
|
||||
if (keyRe.indexIn(line) != -1) {
|
||||
|
||||
QString key = keyRe.cap(1);
|
||||
QString value = keyRe.cap(2);
|
||||
QString key = keyRe.cap(1).trimmed();
|
||||
QString value = keyRe.cap(2).trimmed();
|
||||
|
||||
// Don't remove existing data entries
|
||||
if (key != QLatin1String("data"))
|
||||
|
@ -43,6 +43,7 @@ public:
|
||||
inline QStringList getDataDirs() { return mDataDirs; }
|
||||
inline void addDataDir(const QString &dir) { if(!dir.isEmpty()) mDataDirs.append(dir); }
|
||||
inline QString getDataLocal() {return mDataLocal; }
|
||||
inline bool hasMaster() { return mSettings.count(QString("master")) > 0; }
|
||||
|
||||
QStringList values(const QString &key, const QStringList &defaultValues = QStringList());
|
||||
bool readFile(QTextStream &stream);
|
||||
|
@ -7,14 +7,12 @@
|
||||
#include <QRegExp>
|
||||
#include <QMap>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
template <class Map>
|
||||
class SettingsBase
|
||||
{
|
||||
|
||||
public:
|
||||
SettingsBase() {}
|
||||
SettingsBase() { mMultiValue = false; }
|
||||
~SettingsBase() {}
|
||||
|
||||
inline QString value(const QString &key, const QString &defaultValue = QString())
|
||||
@ -36,6 +34,11 @@ public:
|
||||
mSettings.insertMulti(key, value);
|
||||
}
|
||||
|
||||
inline void setMultiValueEnabled(bool enable)
|
||||
{
|
||||
mMultiValue = enable;
|
||||
}
|
||||
|
||||
inline void remove(const QString &key)
|
||||
{
|
||||
mSettings.remove(key);
|
||||
@ -66,8 +69,8 @@ public:
|
||||
|
||||
if (keyRe.indexIn(line) != -1) {
|
||||
|
||||
QString key = keyRe.cap(1);
|
||||
QString value = keyRe.cap(2);
|
||||
QString key = keyRe.cap(1).trimmed();
|
||||
QString value = keyRe.cap(2).trimmed();
|
||||
|
||||
if (!sectionPrefix.isEmpty())
|
||||
key.prepend(sectionPrefix);
|
||||
@ -75,8 +78,13 @@ public:
|
||||
mSettings.remove(key);
|
||||
|
||||
QStringList values = mCache.values(key);
|
||||
|
||||
if (!values.contains(value)) {
|
||||
mCache.insertMulti(key, value);
|
||||
if (mMultiValue) {
|
||||
mCache.insertMulti(key, value);
|
||||
} else {
|
||||
mCache.insert(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -94,6 +102,8 @@ public:
|
||||
private:
|
||||
Map mSettings;
|
||||
Map mCache;
|
||||
|
||||
bool mMultiValue;
|
||||
};
|
||||
|
||||
#endif // SETTINGSBASE_HPP
|
||||
|
@ -645,7 +645,7 @@ std::string MwIniImporter::numberToString(int n) {
|
||||
return str.str();
|
||||
}
|
||||
|
||||
MwIniImporter::multistrmap MwIniImporter::loadIniFile(std::string filename) {
|
||||
MwIniImporter::multistrmap MwIniImporter::loadIniFile(const std::string& filename) const {
|
||||
std::cout << "load ini file: " << filename << std::endl;
|
||||
|
||||
std::string section("");
|
||||
@ -701,7 +701,7 @@ MwIniImporter::multistrmap MwIniImporter::loadIniFile(std::string filename) {
|
||||
return map;
|
||||
}
|
||||
|
||||
MwIniImporter::multistrmap MwIniImporter::loadCfgFile(std::string filename) {
|
||||
MwIniImporter::multistrmap MwIniImporter::loadCfgFile(const std::string& filename) {
|
||||
std::cout << "load cfg file: " << filename << std::endl;
|
||||
|
||||
MwIniImporter::multistrmap map;
|
||||
@ -738,12 +738,11 @@ MwIniImporter::multistrmap MwIniImporter::loadCfgFile(std::string filename) {
|
||||
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) {
|
||||
void MwIniImporter::merge(multistrmap &cfg, const multistrmap &ini) const {
|
||||
multistrmap::const_iterator iniIt;
|
||||
for(strmap::const_iterator it=mMergeMap.begin(); it!=mMergeMap.end(); ++it) {
|
||||
if((iniIt = ini.find(it->second)) != ini.end()) {
|
||||
for(std::vector<std::string>::iterator vc = iniIt->second.begin(); vc != iniIt->second.end(); ++vc) {
|
||||
for(std::vector<std::string>::const_iterator vc = iniIt->second.begin(); vc != iniIt->second.end(); ++vc) {
|
||||
cfg.erase(it->first);
|
||||
insertMultistrmap(cfg, it->first, *vc);
|
||||
}
|
||||
@ -751,14 +750,13 @@ void MwIniImporter::merge(multistrmap &cfg, multistrmap &ini) {
|
||||
}
|
||||
}
|
||||
|
||||
void MwIniImporter::mergeFallback(multistrmap &cfg, multistrmap &ini) {
|
||||
void MwIniImporter::mergeFallback(multistrmap &cfg, const multistrmap &ini) const {
|
||||
cfg.erase("fallback");
|
||||
|
||||
multistrmap::iterator cfgIt;
|
||||
multistrmap::iterator iniIt;
|
||||
for(std::vector<std::string>::iterator it=mMergeFallback.begin(); it!=mMergeFallback.end(); ++it) {
|
||||
multistrmap::const_iterator iniIt;
|
||||
for(std::vector<std::string>::const_iterator it=mMergeFallback.begin(); it!=mMergeFallback.end(); ++it) {
|
||||
if((iniIt = ini.find(*it)) != ini.end()) {
|
||||
for(std::vector<std::string>::iterator vc = iniIt->second.begin(); vc != iniIt->second.end(); ++vc) {
|
||||
for(std::vector<std::string>::const_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(), ':', '_' );
|
||||
@ -769,21 +767,21 @@ void MwIniImporter::mergeFallback(multistrmap &cfg, multistrmap &ini) {
|
||||
}
|
||||
}
|
||||
|
||||
void MwIniImporter::insertMultistrmap(multistrmap &cfg, std::string key, std::string value) {
|
||||
multistrmap::iterator it = cfg.find(key);
|
||||
void MwIniImporter::insertMultistrmap(multistrmap &cfg, const std::string& key, const std::string& value) {
|
||||
const multistrmap::const_iterator it = cfg.find(key);
|
||||
if(it == cfg.end()) {
|
||||
cfg.insert(std::make_pair (key, std::vector<std::string>() ));
|
||||
}
|
||||
cfg[key].push_back(value);
|
||||
}
|
||||
|
||||
void MwIniImporter::importArchives(multistrmap &cfg, multistrmap &ini) {
|
||||
void MwIniImporter::importArchives(multistrmap &cfg, const multistrmap &ini) const {
|
||||
std::vector<std::string> archives;
|
||||
std::string baseArchive("Archives:Archive ");
|
||||
std::string archive;
|
||||
|
||||
// Search archives listed in ini file
|
||||
multistrmap::iterator it = ini.begin();
|
||||
multistrmap::const_iterator it = ini.begin();
|
||||
for(int i=0; it != ini.end(); i++) {
|
||||
archive = baseArchive;
|
||||
archive.append(this->numberToString(i));
|
||||
@ -793,7 +791,7 @@ void MwIniImporter::importArchives(multistrmap &cfg, multistrmap &ini) {
|
||||
break;
|
||||
}
|
||||
|
||||
for(std::vector<std::string>::iterator entry = it->second.begin(); entry!=it->second.end(); ++entry) {
|
||||
for(std::vector<std::string>::const_iterator entry = it->second.begin(); entry!=it->second.end(); ++entry) {
|
||||
archives.push_back(*entry);
|
||||
}
|
||||
}
|
||||
@ -805,18 +803,18 @@ void MwIniImporter::importArchives(multistrmap &cfg, multistrmap &ini) {
|
||||
// does not appears in the ini file
|
||||
cfg["fallback-archive"].push_back("Morrowind.bsa");
|
||||
|
||||
for(std::vector<std::string>::iterator it=archives.begin(); it!=archives.end(); ++it) {
|
||||
for(std::vector<std::string>::const_iterator it=archives.begin(); it!=archives.end(); ++it) {
|
||||
cfg["fallback-archive"].push_back(*it);
|
||||
}
|
||||
}
|
||||
|
||||
void MwIniImporter::importGameFiles(multistrmap &cfg, multistrmap &ini) {
|
||||
void MwIniImporter::importGameFiles(multistrmap &cfg, const multistrmap &ini) const {
|
||||
std::vector<std::string> esmFiles;
|
||||
std::vector<std::string> espFiles;
|
||||
std::string baseGameFile("Game Files:GameFile");
|
||||
std::string gameFile("");
|
||||
|
||||
multistrmap::iterator it = ini.begin();
|
||||
multistrmap::const_iterator it = ini.begin();
|
||||
for(int i=0; it != ini.end(); i++) {
|
||||
gameFile = baseGameFile;
|
||||
gameFile.append(this->numberToString(i));
|
||||
@ -826,7 +824,7 @@ void MwIniImporter::importGameFiles(multistrmap &cfg, multistrmap &ini) {
|
||||
break;
|
||||
}
|
||||
|
||||
for(std::vector<std::string>::iterator entry = it->second.begin(); entry!=it->second.end(); ++entry) {
|
||||
for(std::vector<std::string>::const_iterator entry = it->second.begin(); entry!=it->second.end(); ++entry) {
|
||||
std::string filetype(entry->substr(entry->length()-3));
|
||||
Misc::StringUtils::toLower(filetype);
|
||||
|
||||
@ -844,22 +842,22 @@ void MwIniImporter::importGameFiles(multistrmap &cfg, multistrmap &ini) {
|
||||
cfg.erase("master");
|
||||
cfg.insert( std::make_pair<std::string, std::vector<std::string> > ("master", std::vector<std::string>() ) );
|
||||
|
||||
for(std::vector<std::string>::iterator it=esmFiles.begin(); it!=esmFiles.end(); ++it) {
|
||||
for(std::vector<std::string>::const_iterator it=esmFiles.begin(); it!=esmFiles.end(); ++it) {
|
||||
cfg["master"].push_back(*it);
|
||||
}
|
||||
|
||||
cfg.erase("plugin");
|
||||
cfg.insert( std::make_pair<std::string, std::vector<std::string> > ("plugin", std::vector<std::string>() ) );
|
||||
|
||||
for(std::vector<std::string>::iterator it=espFiles.begin(); it!=espFiles.end(); ++it) {
|
||||
for(std::vector<std::string>::const_iterator it=espFiles.begin(); it!=espFiles.end(); ++it) {
|
||||
cfg["plugin"].push_back(*it);
|
||||
}
|
||||
}
|
||||
|
||||
void MwIniImporter::writeToFile(boost::iostreams::stream<boost::iostreams::file_sink> &out, multistrmap &cfg) {
|
||||
void MwIniImporter::writeToFile(boost::iostreams::stream<boost::iostreams::file_sink> &out, const multistrmap &cfg) {
|
||||
|
||||
for(multistrmap::iterator it=cfg.begin(); it != cfg.end(); ++it) {
|
||||
for(std::vector<std::string>::iterator entry=it->second.begin(); entry != it->second.end(); ++entry) {
|
||||
for(multistrmap::const_iterator it=cfg.begin(); it != cfg.end(); ++it) {
|
||||
for(std::vector<std::string>::const_iterator entry=it->second.begin(); entry != it->second.end(); ++entry) {
|
||||
out << (it->first) << "=" << (*entry) << std::endl;
|
||||
}
|
||||
}
|
||||
|
@ -18,18 +18,17 @@ class MwIniImporter {
|
||||
MwIniImporter();
|
||||
void setInputEncoding(const ToUTF8::FromType& encoding);
|
||||
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 importArchives(multistrmap &cfg, multistrmap &ini);
|
||||
void writeToFile(boost::iostreams::stream<boost::iostreams::file_sink> &out, multistrmap &cfg);
|
||||
|
||||
multistrmap loadIniFile(const std::string& filename) const;
|
||||
static multistrmap loadCfgFile(const std::string& filename);
|
||||
void merge(multistrmap &cfg, const multistrmap &ini) const;
|
||||
void mergeFallback(multistrmap &cfg, const multistrmap &ini) const;
|
||||
void importGameFiles(multistrmap &cfg, const multistrmap &ini) const;
|
||||
void importArchives(multistrmap &cfg, const multistrmap &ini) const;
|
||||
static void writeToFile(boost::iostreams::stream<boost::iostreams::file_sink> &out, const multistrmap &cfg);
|
||||
|
||||
private:
|
||||
void insertMultistrmap(multistrmap &cfg, std::string key, std::string value);
|
||||
std::string numberToString(int n);
|
||||
std::string toUTF8(const std::string &str);
|
||||
static void insertMultistrmap(multistrmap &cfg, const std::string& key, const std::string& value);
|
||||
static std::string numberToString(int n);
|
||||
bool mVerbose;
|
||||
strmap mMergeMap;
|
||||
std::vector<std::string> mMergeFallback;
|
||||
|
@ -28,12 +28,26 @@ int main(int argc, char *argv[]) {
|
||||
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);
|
||||
try
|
||||
{
|
||||
bpo::parsed_options parsed = bpo::command_line_parser(argc, argv)
|
||||
.options(desc)
|
||||
.positional(p_desc)
|
||||
.run();
|
||||
|
||||
bpo::store(parsed, vm);
|
||||
}
|
||||
catch(boost::program_options::unknown_option & x)
|
||||
{
|
||||
std::cerr << "ERROR: " << x.what() << std::endl;
|
||||
return false;
|
||||
}
|
||||
catch(boost::program_options::invalid_command_line_syntax & x)
|
||||
{
|
||||
std::cerr << "ERROR: " << x.what() << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(vm.count("help") || !vm.count("ini") || !vm.count("cfg")) {
|
||||
std::cout << desc;
|
||||
@ -55,10 +69,8 @@ int main(int argc, char *argv[]) {
|
||||
std::cerr << "ini file does not exist" << std::endl;
|
||||
return -3;
|
||||
}
|
||||
if(!boost::filesystem::exists(cfgFile)) {
|
||||
if(!boost::filesystem::exists(cfgFile))
|
||||
std::cerr << "cfg file does not exist" << std::endl;
|
||||
return -4;
|
||||
}
|
||||
|
||||
MwIniImporter importer;
|
||||
importer.setVerbose(vm.count("verbose"));
|
||||
|
@ -57,11 +57,11 @@ opencs_hdrs_noqt (view/doc
|
||||
|
||||
|
||||
opencs_units (view/world
|
||||
table tablesubview scriptsubview
|
||||
table tablesubview scriptsubview util
|
||||
)
|
||||
|
||||
opencs_units_noqt (view/world
|
||||
dialoguesubview util subviews enumdelegate vartypedelegate scripthighlighter
|
||||
dialoguesubview subviews enumdelegate vartypedelegate scripthighlighter recordstatusdelegate
|
||||
)
|
||||
|
||||
|
||||
@ -79,6 +79,7 @@ opencs_units (view/settings
|
||||
abstractwidget
|
||||
usersettingsdialog
|
||||
editorpage
|
||||
windowpage
|
||||
)
|
||||
|
||||
opencs_units_noqt (view/settings
|
||||
|
@ -61,6 +61,11 @@ void CS::Editor::setupDataFiles()
|
||||
QString path = QString::fromStdString(iter->string());
|
||||
mFileDialog.addFiles(path);
|
||||
}
|
||||
|
||||
//load the settings into the userSettings instance.
|
||||
const QString settingFileName = "opencs.cfg";
|
||||
CSMSettings::UserSettings::instance().loadSettings(settingFileName);
|
||||
|
||||
}
|
||||
|
||||
void CS::Editor::createDocument()
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "view/doc/viewmanager.hpp"
|
||||
#include "view/doc/startup.hpp"
|
||||
#include "view/doc/filedialog.hpp"
|
||||
#include "model/settings/usersettings.hpp"
|
||||
|
||||
namespace CS
|
||||
{
|
||||
@ -17,6 +18,7 @@ namespace CS
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
CSMSettings::UserSettings mUserSettings;
|
||||
CSMDoc::DocumentManager mDocumentManager;
|
||||
CSVDoc::ViewManager mViewManager;
|
||||
CSVDoc::StartupDialogue mStartup;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -52,6 +52,8 @@ namespace CSMDoc
|
||||
|
||||
void createBase();
|
||||
|
||||
void addGmsts();
|
||||
|
||||
void addOptionalGmsts();
|
||||
|
||||
void addOptionalGlobals();
|
||||
|
@ -15,21 +15,31 @@ namespace CSMSettings
|
||||
QStringList *mValues;
|
||||
|
||||
public:
|
||||
|
||||
explicit SettingContainer (QObject *parent = 0);
|
||||
explicit SettingContainer (const QString &value, QObject *parent = 0);
|
||||
|
||||
virtual QString getName() const {return "";}
|
||||
|
||||
/// add a value to the container
|
||||
/// multiple values supported
|
||||
void insert (const QString &value);
|
||||
|
||||
/// update an existing value
|
||||
/// index specifies multiple values
|
||||
void update (const QString &value, int index = 0);
|
||||
|
||||
/// return value at specified index
|
||||
QString getValue (int index = -1) const;
|
||||
|
||||
/// retrieve list of all values
|
||||
inline QStringList *getValues() const { return mValues; }
|
||||
|
||||
/// return size of list
|
||||
int count() const;
|
||||
|
||||
//test for empty container
|
||||
//useful for default-constructed containers returned by QMap when invalid key is passed
|
||||
/// test for empty container
|
||||
/// useful for default-constructed containers returned by QMap when invalid key is passed
|
||||
inline bool isEmpty() const { return (!mValue && !mValues); }
|
||||
|
||||
inline bool isMultiValue() const { return (mValues); }
|
||||
};
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "settingsitem.hpp"
|
||||
|
||||
#include <QStringList>
|
||||
|
||||
bool CSMSettings::SettingsItem::updateItem (const QStringList *values)
|
||||
{
|
||||
QStringList::ConstIterator it = values->begin();
|
||||
@ -66,21 +68,21 @@ bool CSMSettings::SettingsItem::updateItem(int valueListIndex)
|
||||
|
||||
bool CSMSettings::SettingsItem::validate (const QString &value)
|
||||
{
|
||||
bool isValid = true;
|
||||
//if there is no value list or value pair, there is no validation to do
|
||||
bool isValid = !(!mValueList->isEmpty() || mValuePair);
|
||||
|
||||
//validation required only if a value list or min/max value pair has been provided
|
||||
if (mValueList->size()>0)
|
||||
if (!isValid && !mValueList->isEmpty())
|
||||
{
|
||||
for (QStringList::ConstIterator it = mValueList->begin(); it !=mValueList->end(); ++it)
|
||||
for (QStringList::Iterator it = mValueList->begin(); it != mValueList->end(); ++it)
|
||||
// foreach (QString listItem, *mValueList)
|
||||
{
|
||||
isValid = ( value == *it);
|
||||
isValid = (value == *it);
|
||||
|
||||
if (isValid)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
else if (mValuePair)
|
||||
else if (!isValid && mValuePair)
|
||||
{
|
||||
int numVal = value.toInt();
|
||||
|
||||
|
@ -7,12 +7,13 @@
|
||||
|
||||
namespace CSMSettings
|
||||
{
|
||||
/// Represents a setting including metadata
|
||||
/// (valid values, ranges, defaults, and multivalue status
|
||||
class SettingsItem : public SettingContainer
|
||||
{
|
||||
QStringPair *mValuePair;
|
||||
QStringList *mValueList;
|
||||
bool mIsMultiValue;
|
||||
QString mName;
|
||||
QString mDefaultValue;
|
||||
|
||||
public:
|
||||
@ -20,26 +21,41 @@ namespace CSMSettings
|
||||
const QString& defaultValue, QObject *parent = 0)
|
||||
: SettingContainer(defaultValue, parent),
|
||||
mIsMultiValue (isMultiValue), mValueList (0),
|
||||
mName (name), mValuePair (0), mDefaultValue (defaultValue)
|
||||
{}
|
||||
mValuePair (0), mDefaultValue (defaultValue)
|
||||
{
|
||||
QObject::setObjectName(name);
|
||||
}
|
||||
|
||||
/// updateItem overloads for updating setting value
|
||||
/// provided a list of values (multi-valued),
|
||||
/// a specific value
|
||||
/// or an index value corresponding to the mValueList
|
||||
bool updateItem (const QStringList *values);
|
||||
bool updateItem (const QString &value);
|
||||
bool updateItem (int valueListIndex);
|
||||
|
||||
/// retroeve list of valid values for setting
|
||||
inline QStringList *getValueList() { return mValueList; }
|
||||
|
||||
/// write list of valid values for setting
|
||||
inline void setValueList (QStringList *valueList) { mValueList = valueList; }
|
||||
|
||||
/// valuePair used for spin boxes (max / min)
|
||||
inline QStringPair *getValuePair() { return mValuePair; }
|
||||
|
||||
/// set value range (spinbox / integer use)
|
||||
inline void setValuePair (QStringPair valuePair) { mValuePair = new QStringPair(valuePair); }
|
||||
|
||||
inline QString getName () const { return mName; }
|
||||
inline bool isMultivalue () { return mIsMultiValue; }
|
||||
|
||||
void setDefaultValue (const QString &value);
|
||||
QString getDefaultValue () const;
|
||||
|
||||
private:
|
||||
|
||||
/// Verifies that the supplied value is one of the following:
|
||||
/// 1. Within the limits of the value pair (min / max)
|
||||
/// 2. One of the values indicated in the value list
|
||||
bool validate (const QString &value);
|
||||
};
|
||||
}
|
||||
|
@ -8,11 +8,13 @@
|
||||
#include <QMessageBox>
|
||||
#include <QTextCodec>
|
||||
|
||||
#include <QFile>
|
||||
#include <QDebug>
|
||||
|
||||
#include <components/files/configurationmanager.hpp>
|
||||
|
||||
#include "settingcontainer.hpp"
|
||||
|
||||
#include <boost/version.hpp>
|
||||
|
||||
/**
|
||||
* Workaround for problems with whitespaces in paths in older versions of Boost library
|
||||
*/
|
||||
@ -29,109 +31,236 @@ namespace boost
|
||||
} /* namespace boost */
|
||||
#endif /* (BOOST_VERSION <= 104600) */
|
||||
|
||||
CSMSettings::UserSettings *CSMSettings::UserSettings::mUserSettingsInstance = 0;
|
||||
|
||||
CSMSettings::UserSettings::UserSettings()
|
||||
{
|
||||
assert(!mUserSettingsInstance);
|
||||
mUserSettingsInstance = this;
|
||||
|
||||
mReadWriteMessage = QObject::tr("<br><b>Could not open or create file for writing</b><br><br> \
|
||||
Please make sure you have the right permissions and try again.<br>");
|
||||
|
||||
mReadOnlyMessage = QObject::tr("<br><b>Could not open file for reading</b><br><br> \
|
||||
Please make sure you have the right permissions and try again.<br>");
|
||||
}
|
||||
|
||||
CSMSettings::UserSettings::~UserSettings()
|
||||
{
|
||||
mUserSettingsInstance = 0;
|
||||
}
|
||||
|
||||
QFile *CSMSettings::UserSettings::openFile (const QString &filename)
|
||||
QTextStream *CSMSettings::UserSettings::openFileStream (const QString &filePath, bool isReadOnly) const
|
||||
{
|
||||
QFile *file = new QFile(filename);
|
||||
QIODevice::OpenMode openFlags = QIODevice::Text;
|
||||
|
||||
bool success = (file->open(QIODevice::ReadWrite | QIODevice::Text | QIODevice::Truncate)) ;
|
||||
if (isReadOnly)
|
||||
openFlags = QIODevice::ReadOnly | openFlags;
|
||||
else
|
||||
openFlags = QIODevice::ReadWrite | QIODevice::Truncate | openFlags;
|
||||
|
||||
if (!success)
|
||||
QFile *file = new QFile(filePath);
|
||||
QTextStream *stream = 0;
|
||||
|
||||
if (file->open(openFlags))
|
||||
{
|
||||
// File cannot be opened or created
|
||||
QMessageBox msgBox;
|
||||
msgBox.setWindowTitle(QObject::tr("Error writing OpenMW configuration file"));
|
||||
msgBox.setIcon(QMessageBox::Critical);
|
||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||
msgBox.setText(QObject::tr("<br><b>Could not open or create %0 for writing</b><br><br> \
|
||||
Please make sure you have the right permissions \
|
||||
and try again.<br>").arg(file->fileName()));
|
||||
msgBox.exec();
|
||||
delete file;
|
||||
file = 0;
|
||||
stream = new QTextStream(file);
|
||||
stream->setCodec(QTextCodec::codecForName("UTF-8"));
|
||||
}
|
||||
|
||||
return file;
|
||||
return stream;
|
||||
|
||||
}
|
||||
|
||||
bool CSMSettings::UserSettings::writeFile(QFile *file, QMap<QString, CSMSettings::SettingList *> &settings)
|
||||
bool CSMSettings::UserSettings::writeSettings(QMap<QString, CSMSettings::SettingList *> &settings)
|
||||
{
|
||||
if (!file)
|
||||
QTextStream *stream = openFileStream(mUserFilePath);
|
||||
|
||||
bool success = (stream);
|
||||
|
||||
if (success)
|
||||
{
|
||||
QList<QString> keyList = settings.keys();
|
||||
|
||||
foreach (QString key, keyList)
|
||||
{
|
||||
SettingList *sectionSettings = settings[key];
|
||||
|
||||
*stream << "[" << key << "]" << '\n';
|
||||
|
||||
foreach (SettingContainer *item, *sectionSettings)
|
||||
*stream << item->objectName() << " = " << item->getValue() << '\n';
|
||||
}
|
||||
|
||||
stream->device()->close();
|
||||
delete stream;
|
||||
stream = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
displayFileErrorMessage(mReadWriteMessage, false);
|
||||
}
|
||||
|
||||
return (success);
|
||||
}
|
||||
|
||||
|
||||
const CSMSettings::SectionMap &CSMSettings::UserSettings::getSettings() const
|
||||
{
|
||||
return mSectionSettings;
|
||||
}
|
||||
|
||||
bool CSMSettings::UserSettings::loadFromFile(const QString &filePath)
|
||||
{
|
||||
if (filePath.isEmpty())
|
||||
return false;
|
||||
|
||||
QTextStream stream(file);
|
||||
stream.setCodec(QTextCodec::codecForName("UTF-8"));
|
||||
mSectionSettings.clear();
|
||||
|
||||
QList<QString> keyList = settings.keys();
|
||||
QTextStream *stream = openFileStream (filePath, true);
|
||||
|
||||
foreach (QString key, keyList)
|
||||
bool success = (stream);
|
||||
|
||||
if (success)
|
||||
{
|
||||
SettingList *sectionSettings = settings[key];
|
||||
//looks for a square bracket, "'\\["
|
||||
//that has one or more "not nothing" in it, "([^]]+)"
|
||||
//and is closed with a square bracket, "\\]"
|
||||
|
||||
stream << "[" << key << "]" << '\n';
|
||||
QRegExp sectionRe("^\\[([^]]+)\\]");
|
||||
|
||||
foreach (SettingContainer *item, *sectionSettings)
|
||||
stream << item->getName() << " = " << item->getValue() << '\n';
|
||||
//Find any character(s) that is/are not equal sign(s), "[^=]+"
|
||||
//followed by an optional whitespace, an equal sign, and another optional whitespace, "\\s*=\\s*"
|
||||
//and one or more periods, "(.+)"
|
||||
|
||||
QRegExp keyRe("^([^=]+)\\s*=\\s*(.+)$");
|
||||
|
||||
CSMSettings::SettingMap *settings = 0;
|
||||
QString section = "none";
|
||||
|
||||
while (!stream->atEnd())
|
||||
{
|
||||
QString line = stream->readLine().simplified();
|
||||
|
||||
if (line.isEmpty() || line.startsWith("#"))
|
||||
continue;
|
||||
|
||||
//if a section is found, push it onto a new QStringList
|
||||
//and push the QStringList onto
|
||||
if (sectionRe.exactMatch(line))
|
||||
{
|
||||
//add the previous section's settings to the member map
|
||||
if (settings)
|
||||
mSectionSettings.insert(section, settings);
|
||||
|
||||
//save new section and create a new list
|
||||
section = sectionRe.cap(1);
|
||||
settings = new SettingMap;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (keyRe.indexIn(line) != -1)
|
||||
{
|
||||
SettingContainer *sc = new SettingContainer (keyRe.cap(2).simplified());
|
||||
sc->setObjectName(keyRe.cap(1).simplified());
|
||||
(*settings)[keyRe.cap(1).simplified()] = sc;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
mSectionSettings.insert(section, settings);
|
||||
|
||||
stream->device()->close();
|
||||
delete stream;
|
||||
stream = 0;
|
||||
}
|
||||
|
||||
file->close();
|
||||
|
||||
return true;
|
||||
return success;
|
||||
}
|
||||
|
||||
void CSMSettings::UserSettings::getSettings(QTextStream &stream, SectionMap §ions)
|
||||
void CSMSettings::UserSettings::loadSettings (const QString &fileName)
|
||||
{
|
||||
//looks for a square bracket, "'\\["
|
||||
//that has one or more "not nothing" in it, "([^]]+)"
|
||||
//and is closed with a square bracket, "\\]"
|
||||
//global
|
||||
QString globalFilePath = QString::fromStdString(mCfgMgr.getGlobalPath().string()) + fileName;
|
||||
bool globalOk = loadFromFile(globalFilePath);
|
||||
|
||||
QRegExp sectionRe("^\\[([^]]+)\\]");
|
||||
|
||||
//Find any character(s) that is/are not equal sign(s), "[^=]+"
|
||||
//followed by an optional whitespace, an equal sign, and another optional whirespace, "\\s*=\\s*"
|
||||
//and one or more periods, "(.+)"
|
||||
//local
|
||||
QString localFilePath = QString::fromStdString(mCfgMgr.getLocalPath().string()) + fileName;
|
||||
bool localOk = loadFromFile(localFilePath);
|
||||
|
||||
QRegExp keyRe("^([^=]+)\\s*=\\s*(.+)$");
|
||||
//user
|
||||
mUserFilePath = QString::fromStdString(mCfgMgr.getUserPath().string()) + fileName;
|
||||
loadFromFile(mUserFilePath);
|
||||
|
||||
CSMSettings::SettingMap *settings = 0;
|
||||
QString section = "none";
|
||||
|
||||
while (!stream.atEnd())
|
||||
if (!(localOk || globalOk))
|
||||
{
|
||||
QString line = stream.readLine().simplified();
|
||||
QString message = QObject::tr("<br><b>Could not open user settings files for reading</b><br><br> \
|
||||
Global and local settings files could not be read.\
|
||||
You may have incorrect file permissions or the OpenCS installation may be corrupted.<br>");
|
||||
|
||||
if (line.isEmpty() || line.startsWith("#"))
|
||||
continue;
|
||||
|
||||
//if a section is found, push it onto a new QStringList
|
||||
//and push the QStringList onto
|
||||
if (sectionRe.exactMatch(line))
|
||||
{
|
||||
//add the previous section's settings to the member map
|
||||
if (settings)
|
||||
sections.insert(section, settings);
|
||||
|
||||
//save new section and create a new list
|
||||
section = sectionRe.cap(1);
|
||||
settings = new SettingMap;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (keyRe.indexIn(line) != -1)
|
||||
{
|
||||
SettingContainer *sc = new SettingContainer (keyRe.cap(2).simplified());
|
||||
(*settings)[keyRe.cap(1).simplified()] = sc;
|
||||
}
|
||||
message += QObject::tr("<br>Global filepath: ") + globalFilePath;
|
||||
message += QObject::tr("<br>Local filepath: ") + localFilePath;
|
||||
|
||||
displayFileErrorMessage ( message, true);
|
||||
}
|
||||
sections.insert(section, settings);
|
||||
}
|
||||
|
||||
void CSMSettings::UserSettings::updateSettings (const QString §ionName, const QString &settingName)
|
||||
{
|
||||
if (mSectionSettings.find(sectionName) == mSectionSettings.end())
|
||||
return;
|
||||
|
||||
SettingMap *settings = mSectionSettings.value(sectionName);
|
||||
|
||||
if (settingName.isEmpty())
|
||||
{
|
||||
foreach (const SettingContainer *setting, *settings)
|
||||
emit signalUpdateEditorSetting (setting->objectName(), setting->getValue());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (settings->find(settingName) != settings->end())
|
||||
{
|
||||
const SettingContainer *setting = settings->value(settingName);
|
||||
emit signalUpdateEditorSetting (setting->objectName(), setting->getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QString CSMSettings::UserSettings::getSetting (const QString §ion, const QString &setting) const
|
||||
{
|
||||
QString retVal = "";
|
||||
|
||||
if (mSectionSettings.find(section) != mSectionSettings.end())
|
||||
{
|
||||
CSMSettings::SettingMap *settings = mSectionSettings.value(section);
|
||||
|
||||
if (settings->find(setting) != settings->end())
|
||||
retVal = settings->value(setting)->getValue();
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
CSMSettings::UserSettings& CSMSettings::UserSettings::instance()
|
||||
{
|
||||
assert(mUserSettingsInstance);
|
||||
return *mUserSettingsInstance;
|
||||
}
|
||||
|
||||
void CSMSettings::UserSettings::displayFileErrorMessage(const QString &message, bool isReadOnly)
|
||||
{
|
||||
// File cannot be opened or created
|
||||
QMessageBox msgBox;
|
||||
msgBox.setWindowTitle(QObject::tr("OpenCS configuration file I/O error"));
|
||||
msgBox.setIcon(QMessageBox::Critical);
|
||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||
|
||||
if (!isReadOnly)
|
||||
msgBox.setText (mReadWriteMessage + message);
|
||||
else
|
||||
msgBox.setText (message);
|
||||
|
||||
msgBox.exec();
|
||||
}
|
||||
|
@ -10,6 +10,10 @@
|
||||
|
||||
#include "support.hpp"
|
||||
|
||||
#ifndef Q_MOC_RUN
|
||||
#include <components/files/configurationmanager.hpp>
|
||||
#endif
|
||||
|
||||
namespace Files { typedef std::vector<boost::filesystem::path> PathContainer;
|
||||
struct ConfigurationManager;}
|
||||
|
||||
@ -22,29 +26,56 @@ namespace CSMSettings {
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
SectionMap mSectionSettings;
|
||||
static UserSettings *mUserSettingsInstance;
|
||||
QString mUserFilePath;
|
||||
Files::ConfigurationManager mCfgMgr;
|
||||
QString mReadOnlyMessage;
|
||||
QString mReadWriteMessage;
|
||||
|
||||
public:
|
||||
|
||||
static UserSettings &instance()
|
||||
{
|
||||
static UserSettings instance;
|
||||
/// Singleton implementation
|
||||
static UserSettings& instance();
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
QFile *openFile (const QString &);
|
||||
bool writeFile(QFile *file, QMap<QString, SettingList *> §ions);
|
||||
void getSettings (QTextStream &stream, SectionMap &settings);
|
||||
|
||||
private:
|
||||
|
||||
UserSettings *mUserSettingsInstance;
|
||||
UserSettings();
|
||||
~UserSettings();
|
||||
|
||||
UserSettings (UserSettings const &); //not implemented
|
||||
void operator= (UserSettings const &); //not implemented
|
||||
|
||||
/// Writes settings to the last loaded settings file
|
||||
bool writeSettings(QMap<QString, SettingList *> §ions);
|
||||
|
||||
/// Called from editor to trigger signal to update the specified setting.
|
||||
/// If no setting name is specified, all settings found in the specified section are updated.
|
||||
void updateSettings (const QString §ionName, const QString &settingName = "");
|
||||
|
||||
/// Retrieves the settings file at all three levels (global, local and user).
|
||||
|
||||
/// \todo Multi-valued settings are not fully implemented. Setting values
|
||||
/// \todo loaded in later files will always overwrite previously loaded values.
|
||||
void loadSettings (const QString &fileName);
|
||||
|
||||
/// Returns the entire map of settings across all sections
|
||||
const SectionMap &getSettings () const;
|
||||
|
||||
/// Retrieves the value as a QString of the specified setting in the specified section
|
||||
QString getSetting(const QString §ion, const QString &setting) const;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
/// Opens a QTextStream from the provided path as read-only or read-write.
|
||||
QTextStream *openFileStream (const QString &filePath, bool isReadOnly = false) const;
|
||||
|
||||
/// Parses a setting file specified in filePath from the provided text stream.
|
||||
bool loadFromFile (const QString &filePath = "");
|
||||
|
||||
void displayFileErrorMessage(const QString &message, bool isReadOnly);
|
||||
|
||||
signals:
|
||||
|
||||
void signalUpdateEditorSetting (const QString &settingName, const QString &settingValue);
|
||||
|
||||
};
|
||||
|
@ -41,7 +41,8 @@ namespace CSMWorld
|
||||
Display_ArmorType,
|
||||
Display_ClothingType,
|
||||
Display_CreatureType,
|
||||
Display_WeaponType
|
||||
Display_WeaponType,
|
||||
Display_RecordState
|
||||
};
|
||||
|
||||
std::string mTitle;
|
||||
|
@ -53,7 +53,7 @@ namespace CSMWorld
|
||||
template<typename ESXRecordT>
|
||||
struct RecordStateColumn : public Column<ESXRecordT>
|
||||
{
|
||||
RecordStateColumn() : Column<ESXRecordT> ("*", ColumnBase::Display_Integer) {}
|
||||
RecordStateColumn() : Column<ESXRecordT> ("*", ColumnBase::Display_RecordState) {}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
@ -1148,4 +1148,4 @@ namespace CSMWorld
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -41,7 +41,7 @@ CSMWorld::RefIdCollection::RefIdCollection()
|
||||
mColumns.push_back (RefIdColumn ("ID", ColumnBase::Display_String,
|
||||
ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false));
|
||||
baseColumns.mId = &mColumns.back();
|
||||
mColumns.push_back (RefIdColumn ("*", ColumnBase::Display_Integer,
|
||||
mColumns.push_back (RefIdColumn ("*", ColumnBase::Display_RecordState,
|
||||
ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false));
|
||||
baseColumns.mModified = &mColumns.back();
|
||||
mColumns.push_back (RefIdColumn ("Type", ColumnBase::Display_Integer,
|
||||
@ -539,4 +539,4 @@ void CSMWorld::RefIdCollection::load (ESM::ESMReader& reader, bool base, Univers
|
||||
int CSMWorld::RefIdCollection::getAppendIndex (UniversalId::Type type) const
|
||||
{
|
||||
return mData.getAppendIndex (type);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "subview.hpp"
|
||||
|
||||
|
||||
CSVDoc::SubView::SubView (const CSMWorld::UniversalId& id) : mUniversalId (id)
|
||||
{
|
||||
/// \todo add a button to the title bar that clones this sub view
|
||||
@ -15,3 +16,7 @@ CSMWorld::UniversalId CSVDoc::SubView::getUniversalId() const
|
||||
{
|
||||
return mUniversalId;
|
||||
}
|
||||
|
||||
void CSVDoc::SubView::updateEditorSetting (const QString &settingName, const QString &settingValue)
|
||||
{
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ namespace CSVDoc
|
||||
CSMWorld::UniversalId getUniversalId() const;
|
||||
|
||||
virtual void setEditLock (bool locked) = 0;
|
||||
virtual void updateEditorSetting (const QString &, const QString &);
|
||||
|
||||
signals:
|
||||
|
||||
@ -42,4 +43,4 @@ namespace CSVDoc
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -182,7 +182,13 @@ CSVDoc::View::View (ViewManager& viewManager, CSMDoc::Document *document, int to
|
||||
: mViewManager (viewManager), mDocument (document), mViewIndex (totalViews-1),
|
||||
mViewTotal (totalViews)
|
||||
{
|
||||
resize (300, 300); /// \todo get default size from settings and set reasonable minimal size
|
||||
QString width = CSMSettings::UserSettings::instance().getSetting(QString("Window Size"), QString("Width"));
|
||||
QString height = CSMSettings::UserSettings::instance().getSetting(QString("Window Size"), QString("Height"));
|
||||
|
||||
if(width==QString() || height==QString())
|
||||
resize(800, 600);
|
||||
else
|
||||
resize (width.toInt(), height.toInt());
|
||||
|
||||
mSubViewWindow.setDockOptions (QMainWindow::AllowNestedDocks);
|
||||
|
||||
@ -261,11 +267,14 @@ void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id)
|
||||
/// \todo add an user setting to reuse sub views (on a per document basis or on a per top level view basis)
|
||||
|
||||
SubView *view = mSubViewFactory.makeSubView (id, *mDocument);
|
||||
view->setObjectName ("subview");
|
||||
mSubViewWindow.addDockWidget (Qt::TopDockWidgetArea, view);
|
||||
|
||||
connect (view, SIGNAL (focusId (const CSMWorld::UniversalId&)), this,
|
||||
SLOT (addSubView (const CSMWorld::UniversalId&)));
|
||||
|
||||
CSMSettings::UserSettings::instance().updateSettings("Editor", "Record Status Display");
|
||||
|
||||
view->show();
|
||||
}
|
||||
|
||||
@ -374,20 +383,34 @@ void CSVDoc::View::showUserSettings()
|
||||
{
|
||||
CSVSettings::UserSettingsDialog *settingsDialog = new CSVSettings::UserSettingsDialog(this);
|
||||
|
||||
connect (&(CSMSettings::UserSettings::instance()), SIGNAL (signalUpdateEditorSetting (const QString &, const QString &)),
|
||||
this, SLOT (slotUpdateEditorSetting (const QString &, const QString &)) );
|
||||
|
||||
settingsDialog->show();
|
||||
}
|
||||
|
||||
void CSVDoc::View::slotUpdateEditorSetting(const QString &settingName, const QString &settingValue)
|
||||
void CSVDoc::View::resizeViewWidth (int width)
|
||||
{
|
||||
static QString lastValue = "";
|
||||
|
||||
if (lastValue != settingValue)
|
||||
{
|
||||
//evaluate settingName against tokens to determine which function to call to update Editor application.
|
||||
|
||||
lastValue = settingValue;
|
||||
}
|
||||
if (width >= 0)
|
||||
resize (width, geometry().height());
|
||||
}
|
||||
|
||||
void CSVDoc::View::resizeViewHeight (int height)
|
||||
{
|
||||
if (height >= 0)
|
||||
resize (geometry().width(), height);
|
||||
}
|
||||
|
||||
void CSVDoc::View::updateEditorSetting (const QString &settingName, const QString &settingValue)
|
||||
{
|
||||
if (settingName == "Record Status Display")
|
||||
{
|
||||
foreach (QObject *view, mSubViewWindow.children())
|
||||
{
|
||||
if (view->objectName() == "subview")
|
||||
dynamic_cast<CSVDoc::SubView *>(view)->updateEditorSetting (settingName, settingValue);
|
||||
}
|
||||
}
|
||||
else if (settingName == "Width")
|
||||
resizeViewWidth (settingValue.toInt());
|
||||
|
||||
else if (settingName == "Height")
|
||||
resizeViewHeight (settingValue.toInt());
|
||||
}
|
||||
|
@ -68,6 +68,14 @@ namespace CSVDoc
|
||||
|
||||
void exitApplication();
|
||||
|
||||
void loadUserSettings();
|
||||
|
||||
/// User preference function
|
||||
void resizeViewWidth (int width);
|
||||
|
||||
/// User preference function
|
||||
void resizeViewHeight (int height);
|
||||
|
||||
public:
|
||||
|
||||
View (ViewManager& viewManager, CSMDoc::Document *document, int totalViews);
|
||||
@ -88,6 +96,9 @@ namespace CSVDoc
|
||||
|
||||
Operations *getOperations() const;
|
||||
|
||||
/// Function called by view manager when user preferences are updated
|
||||
void updateEditorSetting (const QString &, const QString &);
|
||||
|
||||
signals:
|
||||
|
||||
void newDocumentRequest();
|
||||
@ -102,8 +113,6 @@ namespace CSVDoc
|
||||
|
||||
void abortOperation (int type);
|
||||
|
||||
void slotUpdateEditorSetting (const QString &settingName, const QString &settingValue);
|
||||
|
||||
private slots:
|
||||
|
||||
void newView();
|
||||
|
@ -12,13 +12,14 @@
|
||||
#include "../world/util.hpp"
|
||||
#include "../world/enumdelegate.hpp"
|
||||
#include "../world/vartypedelegate.hpp"
|
||||
#include "../world/recordstatusdelegate.hpp"
|
||||
#include "../settings/usersettingsdialog.hpp"
|
||||
|
||||
#include "view.hpp"
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QtGui/QApplication>
|
||||
#include <QDebug>
|
||||
|
||||
void CSVDoc::ViewManager::updateIndices()
|
||||
{
|
||||
@ -117,6 +118,12 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager)
|
||||
|
||||
mDelegateFactories->add (CSMWorld::ColumnBase::Display_WeaponType,
|
||||
new CSVWorld::EnumDelegateFactory (sWeaponTypes));
|
||||
|
||||
mDelegateFactories->add (CSMWorld::ColumnBase::Display_RecordState,
|
||||
new CSVWorld::RecordStatusDelegateFactory() );
|
||||
|
||||
connect (&CSMSettings::UserSettings::instance(), SIGNAL (signalUpdateEditorSetting (const QString &, const QString &)),
|
||||
this, SLOT (slotUpdateEditorSetting (const QString &, const QString &)));
|
||||
}
|
||||
|
||||
CSVDoc::ViewManager::~ViewManager()
|
||||
@ -343,3 +350,13 @@ void CSVDoc::ViewManager::exitApplication (CSVDoc::View *view)
|
||||
if (notifySaveOnClose (view))
|
||||
QApplication::instance()->exit();
|
||||
}
|
||||
|
||||
void CSVDoc::ViewManager::slotUpdateEditorSetting (const QString &settingName, const QString &settingValue)
|
||||
{
|
||||
if (settingName == "Record Status Display" ||
|
||||
settingName == "Width" || settingName == "Height")
|
||||
{
|
||||
foreach (CSVDoc::View *view, mViews)
|
||||
view->updateEditorSetting (settingName, settingValue);
|
||||
}
|
||||
}
|
||||
|
@ -72,6 +72,9 @@ namespace CSVDoc
|
||||
void progress (int current, int max, int type, int threads, CSMDoc::Document *document);
|
||||
|
||||
void onExitWarningHandler(int state, CSMDoc::Document* document);
|
||||
|
||||
/// connected to update signal in UserSettings
|
||||
void slotUpdateEditorSetting (const QString &, const QString &);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -38,27 +38,27 @@ CSVSettings::AbstractWidget *CSVSettings::AbstractBlock::buildWidget (const QStr
|
||||
{
|
||||
|
||||
case Widget_RadioButton:
|
||||
widg = createSettingWidget<QRadioButton> (def, layout);
|
||||
widg = new SettingWidget<QRadioButton> (def, layout, mBox);
|
||||
break;
|
||||
|
||||
case Widget_SpinBox:
|
||||
widg = createSettingWidget<QSpinBox> (def, layout);
|
||||
widg = new SettingWidget<QSpinBox> (def, layout, mBox);
|
||||
break;
|
||||
|
||||
case Widget_CheckBox:
|
||||
widg = createSettingWidget<QCheckBox> (def, layout);
|
||||
widg = new SettingWidget<QCheckBox> (def, layout, mBox);
|
||||
break;
|
||||
|
||||
case Widget_LineEdit:
|
||||
widg = createSettingWidget<QLineEdit> (def, layout);
|
||||
widg = new SettingWidget<QLineEdit> (def, layout, mBox);
|
||||
break;
|
||||
|
||||
case Widget_ListBox:
|
||||
widg = createSettingWidget<QListWidget> (def, layout);
|
||||
widg = new SettingWidget<QListWidget> (def, layout, mBox);
|
||||
break;
|
||||
|
||||
case Widget_ComboBox:
|
||||
widg = createSettingWidget<QComboBox> (def, layout);
|
||||
widg = new SettingWidget<QComboBox> (def, layout, mBox);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -11,6 +11,7 @@
|
||||
namespace CSVSettings
|
||||
{
|
||||
|
||||
/// Abstract base class for all blocks
|
||||
class AbstractBlock : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -31,40 +32,50 @@ namespace CSVSettings
|
||||
bool isVisible() const;
|
||||
|
||||
virtual CSMSettings::SettingList *getSettings() = 0;
|
||||
|
||||
/// update settings found in the passed map and are encapsulated by the block
|
||||
virtual bool updateSettings (const CSMSettings::SettingMap &settings) = 0;
|
||||
|
||||
/// update callback function called from update slot
|
||||
/// used for updating application-level settings in the editor
|
||||
virtual bool updateBySignal (const QString &name, const QString &value, bool &doEmit)
|
||||
{ return false; }
|
||||
|
||||
protected:
|
||||
|
||||
/// Creates the layout which for the blocks QGroupBox
|
||||
QLayout *createLayout (Orientation direction, bool isZeroMargin, QWidget* parent = 0);
|
||||
|
||||
/// Creates widgets that exist as direct children of the block
|
||||
AbstractWidget *buildWidget (const QString &widgetName, WidgetDef &wDef,
|
||||
QLayout *layout = 0, bool isConnected = true) const;
|
||||
|
||||
template <typename T>
|
||||
AbstractWidget *createSettingWidget (WidgetDef &wDef, QLayout *layout) const
|
||||
{
|
||||
return new SettingWidget<T> (wDef, layout, mBox);
|
||||
}
|
||||
|
||||
QWidget *getParent() const;
|
||||
|
||||
public slots:
|
||||
|
||||
/// enables / disables block-level widgets based on signals from other widgets
|
||||
/// used in ToggleBlock
|
||||
void slotSetEnabled (bool value);
|
||||
|
||||
/// receives updates to applicaion-level settings in the Editor
|
||||
void slotUpdateSetting (const QString &settingName, const QString &settingValue);
|
||||
|
||||
private slots:
|
||||
|
||||
/// receives updates to a setting in the block pushed from the application level
|
||||
void slotUpdate (const QString &value);
|
||||
|
||||
signals:
|
||||
|
||||
//signal to functions outside the settings tab widget
|
||||
/// signal to UserSettings instance
|
||||
void signalUpdateSetting (const QString &propertyName, const QString &propertyValue);
|
||||
|
||||
/// signal to widget for updating widget value
|
||||
void signalUpdateWidget (const QString & value);
|
||||
|
||||
//propertyName and propertyValue are for properties for which the updated setting acts as a proxy
|
||||
/// ProxyBlock use only.
|
||||
/// Name and value correspond to settings for which the block is a proxy.
|
||||
void signalUpdateProxySetting (const QString &propertyName, const QString &propertyValue);
|
||||
};
|
||||
}
|
||||
|
@ -13,12 +13,17 @@
|
||||
CSVSettings::AbstractPage::AbstractPage(QWidget *parent):
|
||||
QWidget(parent)
|
||||
{
|
||||
QGridLayout *pageLayout = new QGridLayout(this);
|
||||
setLayout (pageLayout);
|
||||
}
|
||||
|
||||
CSVSettings::AbstractPage::AbstractPage(const QString &pageName, QWidget *parent):
|
||||
QWidget(parent)
|
||||
{
|
||||
QWidget::setObjectName (pageName);
|
||||
|
||||
QGridLayout *pageLayout = new QGridLayout(this);
|
||||
setLayout (pageLayout);
|
||||
}
|
||||
|
||||
CSVSettings::AbstractPage::~AbstractPage()
|
||||
|
@ -14,6 +14,11 @@ namespace CSVSettings {
|
||||
|
||||
typedef QList<AbstractBlock *> AbstractBlockList;
|
||||
|
||||
/// Abstract base class for all setting pages in the dialog
|
||||
|
||||
/// \todo Scripted implementation of settings should eliminate the need
|
||||
/// \todo derive page classes.
|
||||
/// \todo AbstractPage should be replaced with a general page construction class.
|
||||
class AbstractPage: public QWidget
|
||||
{
|
||||
|
||||
@ -28,18 +33,24 @@ namespace CSVSettings {
|
||||
|
||||
~AbstractPage();
|
||||
|
||||
virtual void setupUi()=0;
|
||||
virtual void setupUi() = 0;
|
||||
|
||||
/// triggers widgiet initialization at the page level. All widgets updated to
|
||||
/// current setting values
|
||||
virtual void initializeWidgets (const CSMSettings::SettingMap &settings) = 0;
|
||||
|
||||
/// retrieve the list of settings local to the page.
|
||||
CSMSettings::SettingList *getSettings();
|
||||
|
||||
void setObjectName();
|
||||
|
||||
protected:
|
||||
|
||||
/// Create a block for the page.
|
||||
/// Block is constructed using passed definition struct
|
||||
/// Page level-layout is created and assigned
|
||||
template <typename S, typename T>
|
||||
AbstractBlock *buildBlock (T &def)
|
||||
AbstractBlock *buildBlock (T *def)
|
||||
{
|
||||
S *block = new S (this);
|
||||
int ret = block->build (def);
|
||||
@ -47,12 +58,12 @@ namespace CSVSettings {
|
||||
if (ret < 0)
|
||||
return 0;
|
||||
|
||||
QWidget::layout()->addWidget (block->getGroupBox());
|
||||
QGroupBox *box = block->getGroupBox();
|
||||
QWidget::layout()->addWidget (box);
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@ class QLayout;
|
||||
|
||||
namespace CSVSettings
|
||||
{
|
||||
/// Abstract base class for widgets which are used in user preferences dialog
|
||||
class AbstractWidget : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -16,45 +17,49 @@ namespace CSVSettings
|
||||
|
||||
public:
|
||||
|
||||
/// Passed layout is assigned the constructed widget.
|
||||
/// if no layout is passed, one is created.
|
||||
explicit AbstractWidget (QLayout *layout = 0, QWidget* parent = 0)
|
||||
: QObject (parent), mLayout (layout)
|
||||
{}
|
||||
|
||||
//retrieve layout for insertion into itemblock
|
||||
/// retrieve layout for insertion into itemblock
|
||||
QLayout *getLayout();
|
||||
|
||||
//create the derived widget instance
|
||||
/// create the derived widget instance
|
||||
void build (QWidget* widget, WidgetDef &def, bool noLabel = false);
|
||||
|
||||
//reference to the derived widget instance
|
||||
/// reference to the derived widget instance
|
||||
virtual QWidget *widget() = 0;
|
||||
|
||||
protected:
|
||||
|
||||
//called by inbound signal for type-specific widget udpates
|
||||
/// Callback called by receiving slot for widget udpates
|
||||
virtual void updateWidget (const QString &value) = 0;
|
||||
|
||||
//converts user-defined enum to Qt equivalents
|
||||
/// Converts user-defined enum to Qt equivalents
|
||||
QFlags<Qt::AlignmentFlag> getAlignment (Alignment flag);
|
||||
|
||||
private:
|
||||
|
||||
//widget initialization utilities
|
||||
/// Creates layout and assigns label and widget as appropriate
|
||||
void createLayout (Orientation direction, bool isZeroMargin);
|
||||
|
||||
/// Creates label and widget according to passed definition
|
||||
void buildLabelAndWidget (QWidget *widget, WidgetDef &def, bool noLabel);
|
||||
|
||||
|
||||
signals:
|
||||
|
||||
//outbound update
|
||||
/// outbound update signal
|
||||
void signalUpdateItem (const QString &value);
|
||||
|
||||
public slots:
|
||||
|
||||
//inbound updates
|
||||
/// receives inbound updates
|
||||
void slotUpdateWidget (const QString &value);
|
||||
|
||||
//Outbound updates from derived widget signal
|
||||
/// Overloads for outbound updates from derived widget signal
|
||||
void slotUpdateItem (const QString &value);
|
||||
void slotUpdateItem (bool value);
|
||||
void slotUpdateItem (int value);
|
||||
|
@ -20,16 +20,11 @@
|
||||
CSVSettings::BlankPage::BlankPage(QWidget *parent):
|
||||
AbstractPage("Blank", parent)
|
||||
{
|
||||
initPage();
|
||||
|
||||
}
|
||||
|
||||
CSVSettings::BlankPage::BlankPage(const QString &title, QWidget *parent):
|
||||
AbstractPage(title, parent)
|
||||
{
|
||||
initPage();
|
||||
}
|
||||
|
||||
void CSVSettings::BlankPage::initPage()
|
||||
{
|
||||
// Hacks to get the stylesheet look properly
|
||||
#ifdef Q_OS_MAC
|
||||
@ -43,10 +38,7 @@ void CSVSettings::BlankPage::initPage()
|
||||
void CSVSettings::BlankPage::setupUi()
|
||||
{
|
||||
QGroupBox *pageBox = new QGroupBox(this);
|
||||
QLayout* pageLayout = new QVBoxLayout();
|
||||
|
||||
setLayout(pageLayout);
|
||||
pageLayout->addWidget(pageBox);
|
||||
layout()->addWidget(pageBox);
|
||||
}
|
||||
|
||||
void CSVSettings::BlankPage::initializeWidgets (const CSMSettings::SettingMap &settings)
|
||||
|
@ -10,6 +10,8 @@ namespace CSVSettings {
|
||||
class UserSettings;
|
||||
class AbstractBlock;
|
||||
|
||||
/// Derived page with no widgets
|
||||
/// Reference use only.
|
||||
class BlankPage : public AbstractPage
|
||||
{
|
||||
|
||||
@ -20,9 +22,6 @@ namespace CSVSettings {
|
||||
|
||||
void setupUi();
|
||||
void initializeWidgets (const CSMSettings::SettingMap &settings);
|
||||
|
||||
private:
|
||||
void initPage();
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@ int CSVSettings::CustomBlock::build(GroupBlockDefList &defList, GroupBlockDefLis
|
||||
for (; listIt != defList.end(); ++listIt)
|
||||
{
|
||||
if (!(*listIt)->isProxy)
|
||||
retVal = buildGroupBlock (*(*listIt));
|
||||
retVal = buildGroupBlock (*listIt);
|
||||
else
|
||||
{
|
||||
mGroupList << proxyBlock;
|
||||
@ -32,7 +32,7 @@ int CSVSettings::CustomBlock::build(GroupBlockDefList &defList, GroupBlockDefLis
|
||||
}
|
||||
|
||||
if (proxyIt != defaultIt)
|
||||
retVal = buildProxyBlock (*(*proxyIt), proxyBlock);
|
||||
retVal = buildProxyBlock (*proxyIt, proxyBlock);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
@ -40,12 +40,12 @@ int CSVSettings::CustomBlock::build(GroupBlockDefList &defList, GroupBlockDefLis
|
||||
CSVSettings::GroupBox *CSVSettings::CustomBlock::buildGroupBox (Orientation orientation)
|
||||
{
|
||||
GroupBox *box = new GroupBox (false, mBox);
|
||||
QLayout *layout = createLayout (orientation, true, box);
|
||||
createLayout (orientation, true, box);
|
||||
|
||||
return box;
|
||||
}
|
||||
|
||||
int CSVSettings::CustomBlock::buildGroupBlock(GroupBlockDef &def)
|
||||
int CSVSettings::CustomBlock::buildGroupBlock(GroupBlockDef *def)
|
||||
{
|
||||
GroupBlock *block = new GroupBlock (getParent());
|
||||
|
||||
@ -57,9 +57,9 @@ int CSVSettings::CustomBlock::buildGroupBlock(GroupBlockDef &def)
|
||||
return block->build(def);
|
||||
}
|
||||
|
||||
int CSVSettings::CustomBlock::buildProxyBlock(GroupBlockDef& def, ProxyBlock *block)
|
||||
int CSVSettings::CustomBlock::buildProxyBlock(GroupBlockDef *def, ProxyBlock *block)
|
||||
{
|
||||
if (def.properties.size() != 1)
|
||||
if (def->settingItems.size() != 1)
|
||||
return -1;
|
||||
|
||||
int retVal = block->build(def);
|
||||
@ -67,7 +67,8 @@ int CSVSettings::CustomBlock::buildProxyBlock(GroupBlockDef& def, ProxyBlock *bl
|
||||
if (retVal != 0)
|
||||
return retVal;
|
||||
|
||||
foreach (QStringList *list, *(def.properties.at(0)->proxyList))
|
||||
// The first settingItem is the proxy setting, containing the list of settings bound to it.
|
||||
foreach (QStringList *list, *(def->settingItems.at(0)->proxyList))
|
||||
{
|
||||
QString proxiedBlockName = list->at(0);
|
||||
|
||||
|
@ -8,6 +8,8 @@ namespace CSVSettings
|
||||
|
||||
class ProxyBlock;
|
||||
|
||||
/// Base class for customized user preference setting blocks
|
||||
/// Special block classes should be derived from CustomBlock
|
||||
class CustomBlock : public AbstractBlock
|
||||
{
|
||||
|
||||
@ -19,18 +21,27 @@ namespace CSVSettings
|
||||
|
||||
explicit CustomBlock (QWidget *parent = 0);
|
||||
|
||||
/// Update settings local to the block
|
||||
bool updateSettings (const CSMSettings::SettingMap &settings);
|
||||
|
||||
/// Retrieve settings local to the block
|
||||
CSMSettings::SettingList *getSettings();
|
||||
|
||||
/// construct the block using the passed definition
|
||||
int build (GroupBlockDefList &defList, GroupBlockDefList::Iterator *it = 0);
|
||||
|
||||
protected:
|
||||
|
||||
/// construct the block groupbox
|
||||
GroupBox *buildGroupBox (Orientation orientation);
|
||||
|
||||
private:
|
||||
|
||||
int buildGroupBlock(GroupBlockDef &def);
|
||||
int buildProxyBlock(GroupBlockDef &def, ProxyBlock *block);
|
||||
/// Construction function for creating a standard GroupBlock child
|
||||
int buildGroupBlock(GroupBlockDef *def);
|
||||
|
||||
/// Construction function for creating a standard ProxyBlock child
|
||||
int buildProxyBlock(GroupBlockDef *def, ProxyBlock *block);
|
||||
};
|
||||
}
|
||||
#endif // CUSTOMBLOCK_HPP
|
||||
|
@ -1,156 +1,46 @@
|
||||
#include "editorpage.hpp"
|
||||
|
||||
#include <QList>
|
||||
#include <QListView>
|
||||
#include <QGroupBox>
|
||||
#include <QRadioButton>
|
||||
#include <QDockWidget>
|
||||
#include <QVBoxLayout>
|
||||
#include <QGridLayout>
|
||||
#include <QStyle>
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
#include <QPlastiqueStyle>
|
||||
#endif
|
||||
|
||||
#include "../../model/settings/usersettings.hpp"
|
||||
#include "groupblock.hpp"
|
||||
#include "toggleblock.hpp"
|
||||
#include "../../model/settings/usersettings.hpp"
|
||||
|
||||
CSVSettings::EditorPage::EditorPage(QWidget *parent):
|
||||
AbstractPage("Editor", parent)
|
||||
CSVSettings::EditorPage::EditorPage(QWidget* parent) :
|
||||
AbstractPage("Display Format", parent)
|
||||
{
|
||||
// Hacks to get the stylesheet look properly
|
||||
#ifdef Q_OS_MAC
|
||||
QPlastiqueStyle *style = new QPlastiqueStyle;
|
||||
//profilesComboBox->setStyle(style);
|
||||
#endif
|
||||
|
||||
setupUi();
|
||||
}
|
||||
|
||||
CSVSettings::GroupBlockDef *CSVSettings::EditorPage::setupRecordStatusDisplay()
|
||||
{
|
||||
GroupBlockDef *statusBlock = new GroupBlockDef(QString("Record Status Display"));
|
||||
|
||||
SettingsItemDef *statusItem = new SettingsItemDef (statusBlock->title, "Icon and Text");
|
||||
*(statusItem->valueList) << QString("Icon and Text") << QString("Icon Only") << QString("Text Only");
|
||||
|
||||
WidgetDef statusWidget (Widget_RadioButton);
|
||||
statusWidget.valueList = statusItem->valueList;
|
||||
|
||||
statusItem->widget = statusWidget;
|
||||
|
||||
statusBlock->settingItems << statusItem;
|
||||
|
||||
return statusBlock;
|
||||
}
|
||||
|
||||
void CSVSettings::EditorPage::setupUi()
|
||||
{
|
||||
GroupBlockDef undoStack (QString("Undo Stack Size"));
|
||||
GroupBlockDef topLevelWindowCount (QString("Maximum Top-Level Window Count"));
|
||||
GroupBlockDef reuseSubwindow (QString("Reuse Subwindows"));
|
||||
GroupBlockDef customWindowSize (QString ("Custom Window Size"));
|
||||
GroupBlockDef definedWindowSize (QString ("Pre-Defined Window Size"));
|
||||
GroupBlockDef windowSizeToggle (QString ("Window Size"));
|
||||
CustomBlockDef windowSize (QString ("Window Size"));
|
||||
|
||||
////////////////////////////
|
||||
//undo stack size property
|
||||
///////////////////////////
|
||||
|
||||
SettingsItemDef *undoStackItem = new SettingsItemDef (undoStack.title, "32");
|
||||
undoStack.properties << undoStackItem;
|
||||
undoStackItem->minMax.left = "0";
|
||||
undoStackItem->minMax.right = "64";
|
||||
|
||||
WidgetDef stackWidget (Widget_SpinBox);
|
||||
stackWidget.minMax = &(undoStackItem->minMax);
|
||||
stackWidget.widgetWidth = 50;
|
||||
|
||||
undoStackItem->widget = stackWidget;
|
||||
|
||||
//////////////////////////////////////
|
||||
//number of top level windows property
|
||||
/////////////////////////////////////
|
||||
|
||||
SettingsItemDef *topLevelItem = new SettingsItemDef (topLevelWindowCount.title, "100");
|
||||
topLevelWindowCount.properties << topLevelItem;
|
||||
topLevelItem->minMax.left = "1";
|
||||
topLevelItem->minMax.right = "256";
|
||||
|
||||
WidgetDef topLvlWinWidget (Widget_SpinBox);
|
||||
topLvlWinWidget.minMax = &(topLevelItem->minMax);
|
||||
topLvlWinWidget.widgetWidth = 50;
|
||||
|
||||
topLevelItem->widget = topLvlWinWidget;
|
||||
|
||||
///////////////////////////
|
||||
//reuse subwindows property
|
||||
////////////////////////////
|
||||
|
||||
SettingsItemDef *reuseSubItem = new SettingsItemDef (reuseSubwindow.title, "Reuse Subwindows");
|
||||
*(reuseSubItem->valueList) << "None" << "Top-Level" << "Document-Level";
|
||||
|
||||
WidgetDef reuseSubWidget (Widget_RadioButton);
|
||||
reuseSubWidget.valueList = (reuseSubItem->valueList);
|
||||
reuseSubWidget.widgetAlignment = Align_Left;
|
||||
|
||||
reuseSubwindow.properties << reuseSubItem;
|
||||
reuseSubItem->widget = reuseSubWidget;
|
||||
|
||||
///////////////////////////////
|
||||
//custom window size properties
|
||||
///////////////////////////////
|
||||
|
||||
//custom width
|
||||
SettingsItemDef *widthItem = new SettingsItemDef ("Window Width", "640");
|
||||
widthItem->widget = WidgetDef (Widget_LineEdit);
|
||||
widthItem->widget.widgetWidth = 45;
|
||||
|
||||
//custom height
|
||||
SettingsItemDef *heightItem = new SettingsItemDef ("Window Height", "480");
|
||||
heightItem->widget = WidgetDef (Widget_LineEdit);
|
||||
heightItem->widget.widgetWidth = 45;
|
||||
heightItem->widget.caption = "x";
|
||||
|
||||
customWindowSize.properties << widthItem << heightItem;
|
||||
customWindowSize.widgetOrientation = Orient_Horizontal;
|
||||
customWindowSize.isVisible = false;
|
||||
|
||||
|
||||
//pre-defined
|
||||
SettingsItemDef *widthByHeightItem = new SettingsItemDef ("Window Size", "640x480");
|
||||
WidgetDef widthByHeightWidget = WidgetDef (Widget_ComboBox);
|
||||
widthByHeightWidget.widgetWidth = 90;
|
||||
*(widthByHeightItem->valueList) << "640x480" << "800x600" << "1024x768";
|
||||
|
||||
QStringList *widthProxy = new QStringList;
|
||||
QStringList *heightProxy = new QStringList;
|
||||
|
||||
(*widthProxy) << "Window Width" << "640" << "800" << "1024";
|
||||
(*heightProxy) << "Window Height" << "480" << "600" << "768";
|
||||
|
||||
*(widthByHeightItem->proxyList) << widthProxy << heightProxy;
|
||||
|
||||
widthByHeightItem->widget = widthByHeightWidget;
|
||||
|
||||
definedWindowSize.properties << widthByHeightItem;
|
||||
definedWindowSize.isProxy = true;
|
||||
definedWindowSize.isVisible = false;
|
||||
|
||||
// window size toggle
|
||||
windowSizeToggle.captions << "Pre-Defined" << "Custom";
|
||||
windowSizeToggle.widgetOrientation = Orient_Vertical;
|
||||
windowSizeToggle.isVisible = false;
|
||||
|
||||
//define a widget for each group in the toggle
|
||||
for (int i = 0; i < 2; i++)
|
||||
windowSizeToggle.widgets << new WidgetDef (Widget_RadioButton);
|
||||
|
||||
windowSizeToggle.widgets.at(0)->isDefault = false;
|
||||
|
||||
windowSize.blockDefList << &windowSizeToggle << &definedWindowSize << &customWindowSize;
|
||||
windowSize.defaultValue = "Custom";
|
||||
|
||||
QGridLayout *pageLayout = new QGridLayout(this);
|
||||
|
||||
setLayout (pageLayout);
|
||||
|
||||
mAbstractBlocks << buildBlock<GroupBlock> (topLevelWindowCount)
|
||||
<< buildBlock<GroupBlock> (reuseSubwindow)
|
||||
<< buildBlock<ToggleBlock> (windowSize)
|
||||
<< buildBlock<GroupBlock> (undoStack);
|
||||
mAbstractBlocks << buildBlock<GroupBlock>(setupRecordStatusDisplay());
|
||||
|
||||
foreach (AbstractBlock *block, mAbstractBlocks)
|
||||
{
|
||||
connect (block, SIGNAL (signalUpdateSetting (const QString &, const QString &)),
|
||||
this, SIGNAL (signalUpdateEditorSetting (const QString &, const QString &)) );
|
||||
}
|
||||
|
||||
connect ( this,
|
||||
SIGNAL ( signalUpdateEditorSetting (const QString &, const QString &)),
|
||||
&(CSMSettings::UserSettings::instance()),
|
||||
SIGNAL ( signalUpdateEditorSetting (const QString &, const QString &)));
|
||||
|
||||
}
|
||||
|
||||
void CSVSettings::EditorPage::initializeWidgets (const CSMSettings::SettingMap &settings)
|
||||
|
@ -1,28 +1,33 @@
|
||||
#ifndef EDITORPAGE_H
|
||||
#define EDITORPAGE_H
|
||||
#ifndef EDITORPAGE_HPP
|
||||
#define EDITORPAGE_HPP
|
||||
|
||||
#include "support.hpp"
|
||||
#include "abstractpage.hpp"
|
||||
|
||||
class QGroupBox;
|
||||
|
||||
namespace CSVSettings {
|
||||
|
||||
class UserSettings;
|
||||
class AbstractBlock;
|
||||
|
||||
namespace CSVSettings
|
||||
{
|
||||
class EditorPage : public AbstractPage
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit EditorPage(QWidget *parent = 0);
|
||||
|
||||
EditorPage(QWidget *parent = 0);
|
||||
|
||||
void setupUi();
|
||||
void initializeWidgets (const CSMSettings::SettingMap &settings);
|
||||
void setupUi();
|
||||
|
||||
private:
|
||||
|
||||
/// User preference view of the record status delegate's icon / text setting
|
||||
GroupBlockDef *setupRecordStatusDisplay();
|
||||
|
||||
signals:
|
||||
|
||||
/// Signals up for changes to editor application-level settings
|
||||
void signalUpdateEditorSetting (const QString &settingName, const QString &settingValue);
|
||||
|
||||
public slots:
|
||||
};
|
||||
}
|
||||
#endif //EDITORPAGE_H
|
||||
|
||||
#endif // EDITORPAGE_HPP
|
||||
|
@ -9,22 +9,22 @@ CSVSettings::GroupBlock::GroupBlock (bool isVisible, QWidget *parent)
|
||||
: AbstractBlock (isVisible, parent)
|
||||
{}
|
||||
|
||||
int CSVSettings::GroupBlock::build (GroupBlockDef &def)
|
||||
int CSVSettings::GroupBlock::build (GroupBlockDef *def)
|
||||
{
|
||||
|
||||
if (def.properties.size() == 0)
|
||||
if (def->settingItems.size() == 0)
|
||||
return -1;
|
||||
|
||||
int retVal = 0;
|
||||
|
||||
setVisible (def.isVisible);
|
||||
setVisible (def->isVisible);
|
||||
|
||||
mBox->setLayout(createLayout (def.widgetOrientation, true));
|
||||
mBox->setLayout(createLayout (def->widgetOrientation, true));
|
||||
|
||||
setObjectName (def.title);
|
||||
mBox->setTitle (def.title);
|
||||
setObjectName (def->title);
|
||||
mBox->setTitle (def->title);
|
||||
|
||||
foreach (SettingsItemDef *itemDef, def.properties)
|
||||
foreach (SettingsItemDef *itemDef, def->settingItems)
|
||||
{
|
||||
ItemBlock *block = new ItemBlock (mBox);
|
||||
|
||||
|
@ -8,6 +8,8 @@ namespace CSVSettings
|
||||
{
|
||||
class ItemBlock;
|
||||
|
||||
/// Base class for group blocks.
|
||||
/// Derived block classes should use CustomBlock
|
||||
class GroupBlock : public AbstractBlock
|
||||
{
|
||||
ItemBlockList mItemBlockList;
|
||||
@ -16,15 +18,24 @@ namespace CSVSettings
|
||||
GroupBlock (QWidget* parent = 0);
|
||||
GroupBlock (bool isVisible, QWidget *parent = 0);
|
||||
|
||||
int build (GroupBlockDef &def);
|
||||
/// build the gorup block based on passed definition
|
||||
int build (GroupBlockDef *def);
|
||||
|
||||
/// update settings local to the group block
|
||||
bool updateSettings (const CSMSettings::SettingMap &settings);
|
||||
|
||||
/// retrieve setting list local to the group block
|
||||
CSMSettings::SettingList *getSettings();
|
||||
|
||||
/// retrieve item block by name from the passed list or local list
|
||||
ItemBlock *getItemBlock (const QString &name, ItemBlockList *blockList = 0);
|
||||
|
||||
/// retrieve the item block by index from the local list
|
||||
ItemBlock *getItemBlock (int index);
|
||||
|
||||
protected:
|
||||
|
||||
/// create block layout based on passed definition
|
||||
int buildLayout (GroupBlockDef &def);
|
||||
|
||||
};
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
namespace CSVSettings
|
||||
{
|
||||
/// Custom implementation of QGroupBox to be used with block classes
|
||||
class GroupBox : public QGroupBox
|
||||
{
|
||||
static const QString INVISIBLE_BOX_STYLE;
|
||||
|
@ -15,22 +15,32 @@ namespace CSVSettings
|
||||
|
||||
ItemBlock (QWidget* parent = 0);
|
||||
|
||||
/// pure virtual function not implemneted
|
||||
bool updateSettings (const CSMSettings::SettingMap &settings) { return false; }
|
||||
|
||||
CSMSettings::SettingList *getSettings ();
|
||||
|
||||
QString getValue () const;
|
||||
|
||||
/// item blocks encapsulate only one setting
|
||||
int getSettingCount();
|
||||
|
||||
/// update setting value and corresponding widget
|
||||
bool update (const QString &value);
|
||||
|
||||
/// virtual construction function
|
||||
int build(SettingsItemDef &iDef);
|
||||
|
||||
private:
|
||||
|
||||
/// custom construction function
|
||||
void buildItemBlock (SettingsItemDef& iDef);
|
||||
void buildItemBlockWidgets (SettingsItemDef& iDef);
|
||||
|
||||
/// update the setting value
|
||||
bool updateItem (const QString &);
|
||||
|
||||
/// callback function triggered when update to application level is signalled
|
||||
bool updateBySignal (const QString &name, const QString &value, bool &doEmit);
|
||||
};
|
||||
}
|
||||
|
@ -5,10 +5,10 @@ CSVSettings::ProxyBlock::ProxyBlock (QWidget *parent)
|
||||
: GroupBlock (parent)
|
||||
{
|
||||
}
|
||||
int CSVSettings::ProxyBlock::build (GroupBlockDef &proxyDef)
|
||||
int CSVSettings::ProxyBlock::build (GroupBlockDef *proxyDef)
|
||||
{
|
||||
//get the list of pre-defined values for the proxy
|
||||
mValueList = proxyDef.properties.at(0)->valueList;
|
||||
mValueList = proxyDef->settingItems.at(0)->valueList;
|
||||
|
||||
bool success = GroupBlock::build(proxyDef);
|
||||
|
||||
@ -53,6 +53,8 @@ bool CSVSettings::ProxyBlock::updateProxiedSettings()
|
||||
|
||||
bool success = false;
|
||||
int i = 0;
|
||||
|
||||
//find the value index of the selected value in the proxy setting
|
||||
for (; i < mValueList->size(); ++i)
|
||||
{
|
||||
success = (value == mValueList->at(i));
|
||||
@ -64,6 +66,7 @@ bool CSVSettings::ProxyBlock::updateProxiedSettings()
|
||||
if (!success)
|
||||
return false;
|
||||
|
||||
// update the containing the proxied item's name
|
||||
foreach (QStringList *list, mProxyList)
|
||||
{
|
||||
if ( list->at(0) == block->objectName())
|
||||
|
@ -9,8 +9,7 @@ namespace CSVSettings
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
//NOTE: mProxyItemBlockList and mProxyList
|
||||
//should be combined into a value pair and stored in one list.
|
||||
/// TODO: Combine mProxyItemBlockList and mProxyList.
|
||||
ItemBlockList mProxiedItemBlockList;
|
||||
ProxyList mProxyList;
|
||||
QStringList *mValueList;
|
||||
@ -20,17 +19,28 @@ namespace CSVSettings
|
||||
explicit ProxyBlock (QWidget *parent = 0);
|
||||
explicit ProxyBlock (ItemBlock *proxyItemBlock, QWidget *parent = 0);
|
||||
|
||||
/// Add a block that contains a proxied setting to the proxy block.
|
||||
void addSetting (ItemBlock* settingBlock, QStringList *proxyList);
|
||||
int build (GroupBlockDef &def);
|
||||
|
||||
int build (GroupBlockDef *def);
|
||||
|
||||
CSMSettings::SettingList *getSettings() { return 0; }
|
||||
|
||||
/// Update settings local to the proxy block pushed from application level
|
||||
bool updateSettings (const CSMSettings::SettingMap &settings);
|
||||
|
||||
/// callback function triggered when update to the application level is signaled.
|
||||
bool updateBySignal (const QString &name, const QString &value, bool &doEmit);
|
||||
|
||||
private:
|
||||
|
||||
/// return the item block of a proxied setting
|
||||
ItemBlock *getProxiedItemBlock (const QString &name);
|
||||
|
||||
/// update the proxy setting with data from the proxied settings
|
||||
bool updateByProxiedSettings(const CSMSettings::SettingMap *settings = 0);
|
||||
|
||||
/// update proxied settings with data from the proxy setting
|
||||
bool updateProxiedSettings();
|
||||
|
||||
private slots:
|
||||
|
@ -16,7 +16,8 @@
|
||||
|
||||
namespace CSVSettings
|
||||
{
|
||||
//VALID FOR RADIOBUTTON / CHECKBOX (or other toggle widget with it's own label)
|
||||
|
||||
/// Generic template for radiobuttons / checkboxes
|
||||
template <typename T1>
|
||||
class SettingWidget : public AbstractWidget
|
||||
{
|
||||
@ -47,6 +48,7 @@ namespace CSVSettings
|
||||
}
|
||||
};
|
||||
|
||||
/// spin box template
|
||||
template <>
|
||||
class SettingWidget <QSpinBox>: public AbstractWidget
|
||||
{
|
||||
@ -90,6 +92,7 @@ namespace CSVSettings
|
||||
|
||||
};
|
||||
|
||||
/// combo box template
|
||||
template <>
|
||||
class SettingWidget <QComboBox>: public CSVSettings::AbstractWidget
|
||||
{
|
||||
@ -142,6 +145,7 @@ namespace CSVSettings
|
||||
|
||||
};
|
||||
|
||||
/// line edit template
|
||||
template <>
|
||||
class SettingWidget <QLineEdit>: public CSVSettings::AbstractWidget
|
||||
{
|
||||
@ -175,6 +179,8 @@ namespace CSVSettings
|
||||
}
|
||||
};
|
||||
|
||||
/// list widget template
|
||||
/// \todo Not fully implemented. Only widget supporting multi-valued settings
|
||||
template <>
|
||||
class SettingWidget <QListWidget>: public CSVSettings::AbstractWidget
|
||||
{
|
||||
|
@ -44,21 +44,44 @@ namespace CSVSettings
|
||||
Align_Right = Qt::AlignRight
|
||||
};
|
||||
|
||||
//template for defining the widget of a property.
|
||||
/// definition struct for widgets
|
||||
struct WidgetDef
|
||||
{
|
||||
WidgetType type; //type of widget providing input
|
||||
int labelWidth; //width of caption label
|
||||
int widgetWidth; //width of input widget
|
||||
Orientation orientation; //label / widget orientation (horizontal / vertical)
|
||||
QString inputMask; //input mask (line edit)
|
||||
QString caption; //label caption. Leave empty for multiple items. See BlockDef::captionList
|
||||
QString value; //widget value. Leave empty for multiple items. See BlockDef::valueList
|
||||
CSMSettings::QStringPair *minMax; //Min/Max QString value pair. If empty, assigned to property item value pair.
|
||||
QStringList *valueList; //value list for list widgets. If left empty, is assigned to property item value list during block build().
|
||||
bool isDefault; //isDefault - determined at runtime.
|
||||
Alignment valueAlignment; //left / center / right-justify text in widget
|
||||
Alignment widgetAlignment; //left / center / right-justify widget in group box
|
||||
/// type of widget providing input
|
||||
WidgetType type;
|
||||
|
||||
/// width of caption label
|
||||
int labelWidth;
|
||||
|
||||
/// width of input widget
|
||||
int widgetWidth;
|
||||
|
||||
/// label / widget orientation (horizontal / vertical)
|
||||
Orientation orientation;
|
||||
|
||||
/// input mask (line edit only)
|
||||
QString inputMask;
|
||||
|
||||
/// label caption. Leave empty for multiple items. See BlockDef::captionList
|
||||
QString caption;
|
||||
|
||||
/// widget value. Leave empty for multiple items. See BlockDef::valueList
|
||||
QString value;
|
||||
|
||||
/// Min/Max QString value pair. If empty, assigned to property item value pair.
|
||||
CSMSettings::QStringPair *minMax;
|
||||
|
||||
/// value list for list widgets. If left empty, is assigned to property item value list during block build().
|
||||
QStringList *valueList;
|
||||
|
||||
/// determined at runtime
|
||||
bool isDefault;
|
||||
|
||||
/// left / center / right-justify text in widget
|
||||
Alignment valueAlignment;
|
||||
|
||||
/// left / center / right-justify widget in group box
|
||||
Alignment widgetAlignment;
|
||||
|
||||
|
||||
WidgetDef() : labelWidth (-1), widgetWidth (-1),
|
||||
@ -79,20 +102,34 @@ namespace CSVSettings
|
||||
|
||||
};
|
||||
|
||||
//Defines the attributes of the property as it is represented in the config file
|
||||
//as well as the UI elements (group box and widget) that serve it.
|
||||
//Only one widget may serve as the input widget for the property.
|
||||
/// Defines the attributes of the setting as it is represented in the config file
|
||||
/// as well as the UI elements (group box and widget) that serve it.
|
||||
/// Only one widget may serve as the input widget for the setting.
|
||||
struct SettingsItemDef
|
||||
{
|
||||
QString name; //property name
|
||||
QStringList *valueList; //list of valid values for the property.
|
||||
//Used to populate option widget captions or list widget item lists (see WidgetDef::caption / value)
|
||||
/// setting name
|
||||
QString name;
|
||||
|
||||
/// list of valid values for the setting
|
||||
QStringList *valueList;
|
||||
|
||||
/// Used to populate option widget captions or list widget item lists (see WidgetDef::caption / value)
|
||||
QString defaultValue;
|
||||
|
||||
/// flag indicating multi-valued setting
|
||||
bool hasMultipleValues;
|
||||
CSMSettings::QStringPair minMax; //minimum / maximum value pair
|
||||
WidgetDef widget; //definition of the input widget for this setting
|
||||
Orientation orientation; //general orientation of the widget / label for this property
|
||||
ProxyList *proxyList; //list of property and corresponding default values for proxy widget
|
||||
|
||||
/// minimum / maximum value pair
|
||||
CSMSettings::QStringPair minMax;
|
||||
|
||||
/// definition of the input widget for this setting
|
||||
WidgetDef widget;
|
||||
|
||||
/// general orientation of the widget / label for this setting
|
||||
Orientation orientation;
|
||||
|
||||
/// list of settings and corresponding default values for proxy widget
|
||||
ProxyList *proxyList;
|
||||
|
||||
SettingsItemDef() : name (""), defaultValue (""), orientation (Orient_Vertical), hasMultipleValues (false)
|
||||
{}
|
||||
@ -104,18 +141,32 @@ namespace CSVSettings
|
||||
};
|
||||
|
||||
|
||||
//Hierarchically, this is a "sub-section" of properties within a section, solely for UI organization.
|
||||
//Does not correlate to config file structure.
|
||||
/// Generic container block
|
||||
struct GroupBlockDef
|
||||
{
|
||||
QString title; //title of the block containing the property or properties of this sub-section
|
||||
QStringList captions; //list of captions for widgets at the block level (not associated with any particular property)
|
||||
WidgetList widgets; //list of widgets at the block level (not associated with any particular property)
|
||||
QList<SettingsItemDef *> properties; //list of the property(ies) which are subordinate to the property block.
|
||||
Orientation widgetOrientation; //general orientation of widgets in group block
|
||||
bool isVisible; //determines whether or not box border/title are visible
|
||||
bool isProxy; //indicates whether or not this block defines a proxy block
|
||||
QString defaultValue; //generic default value attribute
|
||||
/// block title
|
||||
QString title;
|
||||
|
||||
/// list of captions for widgets at the block level (not associated with any particular setting)
|
||||
QStringList captions;
|
||||
|
||||
/// list of widgets at the block level (not associated with any particular setting)
|
||||
WidgetList widgets;
|
||||
|
||||
/// list of the settings which are subordinate to the setting block.
|
||||
QList<SettingsItemDef *> settingItems;
|
||||
|
||||
/// general orientation of widgets in group block
|
||||
Orientation widgetOrientation;
|
||||
|
||||
/// determines whether or not box border/title are visible
|
||||
bool isVisible;
|
||||
|
||||
/// indicates whether or not this block defines a proxy block
|
||||
bool isProxy;
|
||||
|
||||
/// generic default value attribute
|
||||
QString defaultValue;
|
||||
|
||||
GroupBlockDef (): title(""), widgetOrientation (Orient_Vertical), isVisible (true), isProxy (false), defaultValue ("")
|
||||
{}
|
||||
@ -125,11 +176,19 @@ namespace CSVSettings
|
||||
{}
|
||||
};
|
||||
|
||||
/// used to create unique, complex blocks
|
||||
struct CustomBlockDef
|
||||
{
|
||||
/// block title
|
||||
QString title;
|
||||
QString defaultValue; //default value for widgets unique to the custom block
|
||||
GroupBlockDefList blockDefList; //list of settings groups that comprise the settings within the custom block
|
||||
|
||||
/// default value for widgets unique to the custom block
|
||||
QString defaultValue;
|
||||
|
||||
/// list of settings groups that comprise the settings within the custom block
|
||||
GroupBlockDefList blockDefList;
|
||||
|
||||
/// orientation of the widgets within the block
|
||||
Orientation blockOrientation;
|
||||
|
||||
CustomBlockDef (): title (""), defaultValue (""), blockOrientation (Orient_Horizontal)
|
||||
|
@ -7,24 +7,24 @@ CSVSettings::ToggleBlock::ToggleBlock(QWidget *parent) :
|
||||
CustomBlock(parent)
|
||||
{}
|
||||
|
||||
int CSVSettings::ToggleBlock::build(CustomBlockDef &def)
|
||||
int CSVSettings::ToggleBlock::build(CustomBlockDef *def)
|
||||
{
|
||||
if (def.blockDefList.size()==0)
|
||||
if (def->blockDefList.size()==0)
|
||||
return -1;
|
||||
|
||||
QList<GroupBlockDef *>::Iterator it = def.blockDefList.begin();
|
||||
QList<GroupBlockDef *>::Iterator it = def->blockDefList.begin();
|
||||
|
||||
//first def in the list is the def for the toggle block
|
||||
GroupBlockDef *toggleDef = *it++;
|
||||
|
||||
if (toggleDef->captions.size() != def.blockDefList.size()-1 )
|
||||
if (toggleDef->captions.size() != def->blockDefList.size()-1 )
|
||||
return -2;
|
||||
|
||||
if (toggleDef->widgets.size() == 0)
|
||||
return -3;
|
||||
|
||||
//create the toogle block UI structure
|
||||
QLayout *blockLayout = createLayout (def.blockOrientation, true);
|
||||
QLayout *blockLayout = createLayout (def->blockOrientation, true);
|
||||
GroupBox *propertyBox = buildGroupBox (toggleDef->widgetOrientation);
|
||||
|
||||
mBox->setLayout(blockLayout);
|
||||
@ -34,13 +34,13 @@ int CSVSettings::ToggleBlock::build(CustomBlockDef &def)
|
||||
//this manages proxy block construction.
|
||||
//Any settings managed by the proxy setting
|
||||
//must be included in the blocks defined in the list.
|
||||
CustomBlock::build (def.blockDefList, &it);
|
||||
CustomBlock::build (def->blockDefList, &it);
|
||||
|
||||
for (GroupBlockList::iterator it = mGroupList.begin(); it != mGroupList.end(); ++it)
|
||||
propertyBox->layout()->addWidget ((*it)->getGroupBox());
|
||||
|
||||
//build togle widgets, linking them to the settings
|
||||
GroupBox *toggleBox = buildToggleWidgets (*toggleDef, def.defaultValue);
|
||||
GroupBox *toggleBox = buildToggleWidgets (toggleDef, def->defaultValue);
|
||||
|
||||
blockLayout->addWidget(toggleBox);
|
||||
blockLayout->addWidget(propertyBox);
|
||||
@ -49,16 +49,16 @@ int CSVSettings::ToggleBlock::build(CustomBlockDef &def)
|
||||
return 0;
|
||||
}
|
||||
|
||||
CSVSettings::GroupBox *CSVSettings::ToggleBlock::buildToggleWidgets (GroupBlockDef &def, QString &defaultToggle)
|
||||
CSVSettings::GroupBox *CSVSettings::ToggleBlock::buildToggleWidgets (GroupBlockDef *def, QString &defaultToggle)
|
||||
{
|
||||
GroupBox *box = new GroupBox (false, getParent());
|
||||
|
||||
QLayout *layout = createLayout (def.widgetOrientation, true, static_cast<QWidget *>(box));
|
||||
QLayout *layout = createLayout (def->widgetOrientation, true, static_cast<QWidget *>(box));
|
||||
|
||||
for (int i = 0; i < def.widgets.size(); ++i)
|
||||
for (int i = 0; i < def->widgets.size(); ++i)
|
||||
{
|
||||
QString caption = def.captions.at(i);
|
||||
WidgetDef *wDef = def.widgets.at(i);
|
||||
QString caption = def->captions.at(i);
|
||||
WidgetDef *wDef = def->widgets.at(i);
|
||||
|
||||
wDef->caption = caption;
|
||||
wDef->widgetAlignment = Align_Left;
|
||||
|
@ -18,10 +18,12 @@ namespace CSVSettings
|
||||
public:
|
||||
explicit ToggleBlock(QWidget *parent = 0);
|
||||
|
||||
int build (CustomBlockDef &def);
|
||||
int build (CustomBlockDef *def);
|
||||
|
||||
private:
|
||||
GroupBox *buildToggleWidgets (GroupBlockDef &def, QString &defaultToggle);
|
||||
/// Constructor for toggle widgets that are specific to toggle block
|
||||
/// Widgets are not a part of the user preference settings
|
||||
GroupBox *buildToggleWidgets (GroupBlockDef *def, QString &defaultToggle);
|
||||
};
|
||||
}
|
||||
#endif // TOGGLEBLOCK_HPP
|
||||
|
@ -10,25 +10,26 @@
|
||||
#include <QPushButton>
|
||||
#include <QDockWidget>
|
||||
|
||||
#include "blankpage.hpp"
|
||||
#include "editorpage.hpp"
|
||||
#include "../../model/settings/support.hpp"
|
||||
#include <QGridLayout>
|
||||
|
||||
#include "editorpage.hpp"
|
||||
#include "windowpage.hpp"
|
||||
|
||||
#include "../../model/settings/support.hpp"
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include "settingwidget.hpp"
|
||||
#include <QDebug>
|
||||
|
||||
CSVSettings::UserSettingsDialog::UserSettingsDialog(QMainWindow *parent) :
|
||||
QMainWindow (parent), mStackedWidget (0)
|
||||
{
|
||||
setWindowTitle(QString::fromUtf8 ("User Settings"));
|
||||
buildPages();
|
||||
setWidgetStates (loadSettings());
|
||||
positionWindow ();
|
||||
setWidgetStates ();
|
||||
|
||||
connect (mListWidget,
|
||||
SIGNAL (currentItemChanged(QListWidgetItem*, QListWidgetItem*)),
|
||||
this,
|
||||
SLOT (slotChangePage (QListWidgetItem*, QListWidgetItem*)));
|
||||
SLOT (slotChangePage (QListWidgetItem*, QListWidgetItem*)));
|
||||
}
|
||||
|
||||
CSVSettings::UserSettingsDialog::~UserSettingsDialog()
|
||||
@ -40,17 +41,21 @@ void CSVSettings::UserSettingsDialog::closeEvent (QCloseEvent *event)
|
||||
writeSettings();
|
||||
}
|
||||
|
||||
void CSVSettings::UserSettingsDialog::setWidgetStates (CSMSettings::SectionMap settingsMap)
|
||||
void CSVSettings::UserSettingsDialog::setWidgetStates ()
|
||||
{
|
||||
CSMSettings::UserSettings::instance().loadSettings("opencs.cfg");
|
||||
const CSMSettings::SectionMap §ionSettings = CSMSettings::UserSettings::instance().getSettings();
|
||||
|
||||
//iterate the tabWidget's pages (sections)
|
||||
for (int i = 0; i < mStackedWidget->count(); i++)
|
||||
{
|
||||
//get the settings defined for the entire section
|
||||
CSMSettings::SettingMap *settings = settingsMap [mStackedWidget->widget(i)->objectName()];
|
||||
//and update widget
|
||||
QString pageName = mStackedWidget->widget(i)->objectName();
|
||||
|
||||
//if found, initialize the page's widgets
|
||||
if (settings)
|
||||
if (sectionSettings.find(pageName) != sectionSettings.end())
|
||||
{
|
||||
CSMSettings::SettingMap *settings = sectionSettings.value(pageName);
|
||||
AbstractPage *page = getAbstractPage (i);
|
||||
page->initializeWidgets(*settings);
|
||||
}
|
||||
@ -65,83 +70,24 @@ void CSVSettings::UserSettingsDialog::buildPages()
|
||||
mListWidget = new QListWidget (centralWidget);
|
||||
mStackedWidget = new QStackedWidget (centralWidget);
|
||||
|
||||
QLayout* dialogLayout = new QHBoxLayout();
|
||||
QGridLayout* dialogLayout = new QGridLayout();
|
||||
|
||||
dialogLayout->addWidget (mListWidget);
|
||||
dialogLayout->addWidget (mStackedWidget);
|
||||
mListWidget->setMinimumWidth(0);
|
||||
mListWidget->setSizePolicy (QSizePolicy::Preferred, QSizePolicy::Expanding);
|
||||
|
||||
mStackedWidget->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
|
||||
dialogLayout->addWidget (mListWidget,0,0);
|
||||
dialogLayout->addWidget (mStackedWidget,0,1, Qt::AlignTop);
|
||||
|
||||
centralWidget->setLayout (dialogLayout);
|
||||
|
||||
setCentralWidget (centralWidget);
|
||||
setDockOptions (QMainWindow::AllowNestedDocks);
|
||||
//uncomment to test with sample editor page.
|
||||
//createSamplePage();
|
||||
createPage<BlankPage>("Page1");
|
||||
createPage<BlankPage>("Page2");
|
||||
createPage<BlankPage>("Page3");
|
||||
}
|
||||
|
||||
void CSVSettings::UserSettingsDialog::createSamplePage()
|
||||
{
|
||||
//add pages to stackedwidget and items to listwidget
|
||||
CSVSettings::AbstractPage *page
|
||||
= new CSVSettings::EditorPage(this);
|
||||
createPage<WindowPage>();
|
||||
createPage<EditorPage>();
|
||||
|
||||
mStackedWidget->addWidget (page);
|
||||
|
||||
new QListWidgetItem (page->objectName(), mListWidget);
|
||||
|
||||
connect ( page, SIGNAL ( signalUpdateEditorSetting (const QString &, const QString &)),
|
||||
&(CSMSettings::UserSettings::instance()), SIGNAL ( signalUpdateEditorSetting (const QString &, const QString &)));
|
||||
}
|
||||
|
||||
void CSVSettings::UserSettingsDialog::positionWindow ()
|
||||
{
|
||||
QRect scr = QApplication::desktop()->screenGeometry();
|
||||
|
||||
move(scr.center().x() - (width() / 2), scr.center().y() - (height() / 2));
|
||||
|
||||
}
|
||||
|
||||
CSMSettings::SectionMap CSVSettings::UserSettingsDialog::loadSettings ()
|
||||
{
|
||||
QString userPath = QString::fromStdString(mCfgMgr.getUserPath().string());
|
||||
|
||||
mPaths.append(QString("opencs.cfg"));
|
||||
mPaths.append(userPath + QString("opencs.cfg"));
|
||||
|
||||
CSMSettings::SectionMap settingsMap;
|
||||
|
||||
foreach (const QString &path, mPaths)
|
||||
{
|
||||
qDebug() << "Loading config file:" << qPrintable(path);
|
||||
QFile file(path);
|
||||
|
||||
if (file.exists())
|
||||
{
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
|
||||
{
|
||||
QMessageBox msgBox;
|
||||
msgBox.setWindowTitle(tr("Error opening OpenCS configuration file"));
|
||||
msgBox.setIcon(QMessageBox::Critical);
|
||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||
msgBox.setText(QObject::tr("<br><b>Could not open %0 for reading</b><br><br> \
|
||||
Please make sure you have the right permissions \
|
||||
and try again.<br>").arg(file.fileName()));
|
||||
msgBox.exec();
|
||||
return settingsMap;
|
||||
}
|
||||
|
||||
QTextStream stream(&file);
|
||||
stream.setCodec(QTextCodec::codecForName("UTF-8"));
|
||||
|
||||
CSMSettings::UserSettings::instance().getSettings(stream, settingsMap);
|
||||
}
|
||||
|
||||
file.close();
|
||||
}
|
||||
|
||||
return settingsMap;
|
||||
}
|
||||
|
||||
void CSVSettings::UserSettingsDialog::writeSettings()
|
||||
@ -153,9 +99,7 @@ void CSVSettings::UserSettingsDialog::writeSettings()
|
||||
AbstractPage *page = getAbstractPage (i);
|
||||
settings [page->objectName()] = page->getSettings();
|
||||
}
|
||||
|
||||
CSMSettings::UserSettings::instance().writeFile(CSMSettings::UserSettings::instance().openFile(mPaths.back()), settings);
|
||||
|
||||
CSMSettings::UserSettings::instance().writeSettings(settings);
|
||||
}
|
||||
|
||||
CSVSettings::AbstractPage *CSVSettings::UserSettingsDialog::getAbstractPage (int index)
|
||||
|
@ -4,14 +4,13 @@
|
||||
#include <QMainWindow>
|
||||
#include <QStackedWidget>
|
||||
#include <QListWidgetItem>
|
||||
|
||||
#ifndef Q_MOC_RUN
|
||||
#include <components/files/configurationmanager.hpp>
|
||||
#endif
|
||||
#include <QApplication>
|
||||
|
||||
#include "../../model/settings/usersettings.hpp"
|
||||
#include "../../model/settings/support.hpp"
|
||||
|
||||
#include "editorpage.hpp"
|
||||
|
||||
class QHBoxLayout;
|
||||
class AbstractWidget;
|
||||
class QStackedWidget;
|
||||
@ -25,10 +24,8 @@ namespace CSVSettings {
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
QStringList mPaths;
|
||||
QListWidget *mListWidget;
|
||||
QStackedWidget *mStackedWidget;
|
||||
Files::ConfigurationManager mCfgMgr;
|
||||
|
||||
public:
|
||||
UserSettingsDialog(QMainWindow *parent = 0);
|
||||
@ -36,35 +33,39 @@ namespace CSVSettings {
|
||||
|
||||
private:
|
||||
|
||||
/// Settings are written on close
|
||||
void closeEvent (QCloseEvent *event);
|
||||
AbstractPage *getAbstractPage (int index);
|
||||
void setWidgetStates (CSMSettings::SectionMap settingsMap);
|
||||
void buildPages();
|
||||
void positionWindow ();
|
||||
CSMSettings::SectionMap loadSettings();
|
||||
void writeSettings();
|
||||
void createSamplePage();
|
||||
|
||||
/// return the setting page by name
|
||||
/// performs dynamic cast to AbstractPage *
|
||||
AbstractPage *getAbstractPage (int index);
|
||||
void setWidgetStates ();
|
||||
void buildPages();
|
||||
void writeSettings();
|
||||
|
||||
/// Templated function to create a custom user preference page
|
||||
template <typename T>
|
||||
void createPage (const QString &title)
|
||||
void createPage ()
|
||||
{
|
||||
T *page = new T(title, this);
|
||||
T *page = new T(mStackedWidget);
|
||||
|
||||
mStackedWidget->addWidget (dynamic_cast<QWidget *>(page));
|
||||
|
||||
new QListWidgetItem (page->objectName(), mListWidget);
|
||||
|
||||
//finishing touches
|
||||
if (mStackedWidget->sizeHint().width() < 640)
|
||||
mStackedWidget->sizeHint().setWidth(640);
|
||||
QFontMetrics fm (QApplication::font());
|
||||
int textWidth = fm.width(page->objectName());
|
||||
|
||||
if (mStackedWidget->sizeHint().height() < 480)
|
||||
mStackedWidget->sizeHint().setHeight(480);
|
||||
if ((textWidth + 50) > mListWidget->minimumWidth())
|
||||
mListWidget->setMinimumWidth(textWidth + 50);
|
||||
|
||||
resize (mStackedWidget->sizeHint());
|
||||
}
|
||||
|
||||
public slots:
|
||||
|
||||
/// Called when a different page is selected in the left-hand list widget
|
||||
void slotChangePage (QListWidgetItem*, QListWidgetItem*);
|
||||
};
|
||||
|
||||
|
144
apps/opencs/view/settings/windowpage.cpp
Normal file
144
apps/opencs/view/settings/windowpage.cpp
Normal file
@ -0,0 +1,144 @@
|
||||
#include "windowpage.hpp"
|
||||
|
||||
#include <QList>
|
||||
#include <QListView>
|
||||
#include <QGroupBox>
|
||||
#include <QRadioButton>
|
||||
#include <QDockWidget>
|
||||
#include <QVBoxLayout>
|
||||
#include <QGridLayout>
|
||||
#include <QStyle>
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
#include <QPlastiqueStyle>
|
||||
#endif
|
||||
|
||||
#include "../../model/settings/usersettings.hpp"
|
||||
#include "groupblock.hpp"
|
||||
#include "toggleblock.hpp"
|
||||
#include "../../view/settings/abstractblock.hpp"
|
||||
|
||||
CSVSettings::WindowPage::WindowPage(QWidget *parent):
|
||||
AbstractPage("Window", parent)
|
||||
{
|
||||
// Hacks to get the stylesheet look properly
|
||||
#ifdef Q_OS_MAC
|
||||
QPlastiqueStyle *style = new QPlastiqueStyle;
|
||||
//profilesComboBox->setStyle(style);
|
||||
#endif
|
||||
|
||||
setupUi();
|
||||
}
|
||||
|
||||
CSVSettings::GroupBlockDef * CSVSettings::WindowPage::buildDefinedWindowSize()
|
||||
{
|
||||
GroupBlockDef *block = new GroupBlockDef ( "Defined Size");
|
||||
|
||||
SettingsItemDef *widthByHeightItem = new SettingsItemDef ("Window Size", "640x480");
|
||||
WidgetDef widthByHeightWidget = WidgetDef (Widget_ComboBox);
|
||||
widthByHeightWidget.widgetWidth = 90;
|
||||
*(widthByHeightItem->valueList) << "640x480" << "800x600" << "1024x768" << "1440x900";
|
||||
|
||||
QStringList *widthProxy = new QStringList;
|
||||
QStringList *heightProxy = new QStringList;
|
||||
|
||||
(*widthProxy) << "Width" << "640" << "800" << "1024" << "1440";
|
||||
(*heightProxy) << "Height" << "480" << "600" << "768" << "900";
|
||||
|
||||
*(widthByHeightItem->proxyList) << widthProxy << heightProxy;
|
||||
|
||||
widthByHeightItem->widget = widthByHeightWidget;
|
||||
|
||||
block->settingItems << widthByHeightItem;
|
||||
block->isProxy = true;
|
||||
block->isVisible = false;
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
CSVSettings::GroupBlockDef *CSVSettings::WindowPage::buildCustomWindowSize()
|
||||
{
|
||||
GroupBlockDef *block = new GroupBlockDef ("Custom Size");
|
||||
|
||||
//custom width
|
||||
SettingsItemDef *widthItem = new SettingsItemDef ("Width", "640");
|
||||
widthItem->widget = WidgetDef (Widget_LineEdit);
|
||||
widthItem->widget.widgetWidth = 45;
|
||||
widthItem->widget.inputMask = "9999";
|
||||
|
||||
//custom height
|
||||
SettingsItemDef *heightItem = new SettingsItemDef ("Height", "480");
|
||||
heightItem->widget = WidgetDef (Widget_LineEdit);
|
||||
heightItem->widget.widgetWidth = 45;
|
||||
heightItem->widget.caption = "x";
|
||||
heightItem->widget.inputMask = "9999";
|
||||
|
||||
block->settingItems << widthItem << heightItem;
|
||||
block->widgetOrientation = Orient_Horizontal;
|
||||
block->isVisible = false;
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
CSVSettings::GroupBlockDef *CSVSettings::WindowPage::buildWindowSizeToggle()
|
||||
{
|
||||
GroupBlockDef *block = new GroupBlockDef ("Window Size");
|
||||
|
||||
// window size toggle
|
||||
block->captions << "Pre-Defined" << "Custom";
|
||||
block->widgetOrientation = Orient_Vertical;
|
||||
block->isVisible = false;
|
||||
|
||||
//define a widget for each group in the toggle
|
||||
for (int i = 0; i < 2; i++)
|
||||
block->widgets << new WidgetDef (Widget_RadioButton);
|
||||
|
||||
block->widgets.at(0)->isDefault = false;
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
CSVSettings::CustomBlockDef *CSVSettings::WindowPage::buildWindowSize(GroupBlockDef *toggle_def,
|
||||
GroupBlockDef *defined_def,
|
||||
GroupBlockDef *custom_def)
|
||||
{
|
||||
CustomBlockDef *block = new CustomBlockDef(QString ("Window Size"));
|
||||
|
||||
block->blockDefList << toggle_def << defined_def << custom_def;
|
||||
block->defaultValue = "Custom";
|
||||
|
||||
return block;
|
||||
|
||||
}
|
||||
|
||||
void CSVSettings::WindowPage::setupUi()
|
||||
{
|
||||
CustomBlockDef *windowSize = buildWindowSize(buildWindowSizeToggle(),
|
||||
buildDefinedWindowSize(),
|
||||
buildCustomWindowSize()
|
||||
);
|
||||
|
||||
mAbstractBlocks << buildBlock<ToggleBlock> (windowSize);
|
||||
|
||||
foreach (AbstractBlock *block, mAbstractBlocks)
|
||||
{
|
||||
connect (block, SIGNAL (signalUpdateSetting (const QString &, const QString &)),
|
||||
this, SIGNAL (signalUpdateEditorSetting (const QString &, const QString &)) );
|
||||
}
|
||||
|
||||
connect ( this,
|
||||
SIGNAL ( signalUpdateEditorSetting (const QString &, const QString &)),
|
||||
&(CSMSettings::UserSettings::instance()),
|
||||
SIGNAL ( signalUpdateEditorSetting (const QString &, const QString &)));
|
||||
|
||||
}
|
||||
|
||||
|
||||
void CSVSettings::WindowPage::initializeWidgets (const CSMSettings::SettingMap &settings)
|
||||
{
|
||||
//iterate each item in each blocks in this section
|
||||
//validate the corresponding setting against the defined valuelist if any.
|
||||
for (AbstractBlockList::Iterator it_block = mAbstractBlocks.begin();
|
||||
it_block != mAbstractBlocks.end(); ++it_block)
|
||||
(*it_block)->updateSettings (settings);
|
||||
}
|
34
apps/opencs/view/settings/windowpage.hpp
Normal file
34
apps/opencs/view/settings/windowpage.hpp
Normal file
@ -0,0 +1,34 @@
|
||||
#ifndef WINDOWPAGE_H
|
||||
#define WINDOWPAGE_H
|
||||
|
||||
#include "abstractpage.hpp"
|
||||
|
||||
class QGroupBox;
|
||||
|
||||
namespace CSVSettings {
|
||||
|
||||
class UserSettings;
|
||||
class AbstractBlock;
|
||||
|
||||
class WindowPage : public AbstractPage
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
WindowPage(QWidget *parent = 0);
|
||||
|
||||
void setupUi();
|
||||
void initializeWidgets (const CSMSettings::SettingMap &settings);
|
||||
|
||||
///
|
||||
GroupBlockDef *buildCustomWindowSize();
|
||||
GroupBlockDef *buildDefinedWindowSize();
|
||||
GroupBlockDef *buildWindowSizeToggle();
|
||||
CustomBlockDef *buildWindowSize (GroupBlockDef *, GroupBlockDef *, GroupBlockDef *);
|
||||
|
||||
signals:
|
||||
void signalUpdateEditorSetting (const QString &settingName, const QString &settingValue);
|
||||
};
|
||||
}
|
||||
#endif //WINDOWPAGE_H
|
122
apps/opencs/view/world/recordstatusdelegate.cpp
Normal file
122
apps/opencs/view/world/recordstatusdelegate.cpp
Normal file
@ -0,0 +1,122 @@
|
||||
#include "recordstatusdelegate.hpp"
|
||||
#include <QPainter>
|
||||
#include <QApplication>
|
||||
#include <QUndoStack>
|
||||
#include "../../model/settings/usersettings.hpp"
|
||||
|
||||
CSVWorld::RecordStatusDelegate::RecordStatusDelegate(QUndoStack &undoStack, QObject *parent)
|
||||
: CommandDelegate (undoStack, parent)
|
||||
{
|
||||
mModifiedIcon = new QIcon (":./modified.png");
|
||||
mAddedIcon = new QIcon (":./added.png");
|
||||
mDeletedIcon = new QIcon (":./removed.png");
|
||||
mBaseIcon = new QIcon (":./base.png");
|
||||
mIconSize = 16;
|
||||
|
||||
//Offset values are most likely device-dependent.
|
||||
//Need to replace with device-independent references.
|
||||
mTextLeftOffset = 3;
|
||||
mIconTopOffset = -3;
|
||||
|
||||
mStatusDisplay = 0; //icons and text by default. Remove when implemented as a user preference
|
||||
|
||||
mFont = QApplication::font();
|
||||
mFont.setPointSize(10);
|
||||
|
||||
mFontMetrics = new QFontMetrics(mFont);
|
||||
|
||||
mTextAlignment.setAlignment (Qt::AlignLeft | Qt::AlignVCenter );
|
||||
}
|
||||
|
||||
void CSVWorld::RecordStatusDelegate::paint (QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||
{
|
||||
painter->save();
|
||||
|
||||
QString text = "";
|
||||
QIcon *icon = 0;
|
||||
|
||||
switch (index.data().toInt())
|
||||
{
|
||||
case 0: // State_BaseOnly
|
||||
text = "Base";
|
||||
icon = mBaseIcon;
|
||||
break;
|
||||
|
||||
case 1: // State_Modified
|
||||
text = "Modified";
|
||||
icon = mModifiedIcon;
|
||||
break;
|
||||
|
||||
case 2: // State_Modified_Only
|
||||
text = "Added";
|
||||
icon = mAddedIcon;
|
||||
break;
|
||||
|
||||
case 3: // State_Deleted
|
||||
|
||||
case 4: // State_Erased
|
||||
text = "Deleted";
|
||||
icon = mDeletedIcon;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
QRect textRect = option.rect;
|
||||
QRect iconRect = option.rect;
|
||||
|
||||
//for icon-only (1), default option.rect centers icon left-to-right
|
||||
//otherwise, size option.rect to fit the icon, forcing left-alignment with text
|
||||
iconRect.setTop (iconRect.top() + mIconTopOffset);
|
||||
iconRect.setBottom (iconRect.top() + mIconSize);
|
||||
|
||||
if (mStatusDisplay == 0 && (icon) )
|
||||
{
|
||||
iconRect.setRight (iconRect.left()+ mIconSize*2);
|
||||
textRect.setLeft (iconRect.right() + mTextLeftOffset *1.25);
|
||||
}
|
||||
else
|
||||
textRect.setLeft (textRect.left() + mTextLeftOffset );
|
||||
|
||||
if ( (mStatusDisplay == 0 || mStatusDisplay == 1) && (icon) )
|
||||
painter->drawPixmap(iconRect.center().x()-10,iconRect.center().y()+2, icon->pixmap(mIconSize, mIconSize));
|
||||
|
||||
// icon + text or text only, or force text if no icon exists for status
|
||||
if (mStatusDisplay == 0 || mStatusDisplay == 2 || !(icon) )
|
||||
{
|
||||
painter->setFont(mFont);
|
||||
painter->drawText(textRect, text, mTextAlignment);
|
||||
}
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
QSize CSVWorld::RecordStatusDelegate::sizeHint (const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||
{
|
||||
return QSize();
|
||||
}
|
||||
|
||||
CSVWorld::CommandDelegate *CSVWorld::RecordStatusDelegateFactory::makeDelegate (QUndoStack& undoStack,
|
||||
QObject *parent) const
|
||||
{
|
||||
return new RecordStatusDelegate (undoStack, parent);
|
||||
}
|
||||
|
||||
void CSVWorld::RecordStatusDelegate::updateEditorSetting (const QString &settingName, const QString &settingValue)
|
||||
{
|
||||
if (settingName == "Record Status Display")
|
||||
{
|
||||
if (settingValue == "Icon and Text")
|
||||
mStatusDisplay = 0;
|
||||
|
||||
else if (settingValue == "Icon Only")
|
||||
mStatusDisplay = 1;
|
||||
|
||||
else if (settingValue == "Text Only")
|
||||
mStatusDisplay = 2;
|
||||
|
||||
else
|
||||
mStatusDisplay = 0;
|
||||
}
|
||||
}
|
53
apps/opencs/view/world/recordstatusdelegate.hpp
Normal file
53
apps/opencs/view/world/recordstatusdelegate.hpp
Normal file
@ -0,0 +1,53 @@
|
||||
#ifndef RECORDSTATUSDELEGATE_H
|
||||
#define RECORDSTATUSDELEGATE_H
|
||||
|
||||
#include "util.hpp"
|
||||
#include <QTextOption>
|
||||
#include <QFont>
|
||||
|
||||
class QIcon;
|
||||
class QFont;
|
||||
class QFontMetrics;
|
||||
|
||||
namespace CSVWorld
|
||||
{
|
||||
class RecordStatusDelegate : public CommandDelegate
|
||||
{
|
||||
QFont mFont;
|
||||
QFontMetrics *mFontMetrics;
|
||||
|
||||
QTextOption mTextAlignment;
|
||||
|
||||
QIcon *mModifiedIcon;
|
||||
QIcon *mAddedIcon;
|
||||
QIcon *mDeletedIcon;
|
||||
QIcon *mBaseIcon;
|
||||
|
||||
int mStatusDisplay;
|
||||
|
||||
int mIconSize;
|
||||
int mIconTopOffset;
|
||||
int mTextLeftOffset;
|
||||
|
||||
public:
|
||||
explicit RecordStatusDelegate(QUndoStack& undoStack, QObject *parent = 0);
|
||||
|
||||
void paint (QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
||||
|
||||
QSize sizeHint (const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
||||
|
||||
void updateEditorSetting (const QString &settingName, const QString &settingValue);
|
||||
|
||||
};
|
||||
|
||||
class RecordStatusDelegateFactory : public CommandDelegateFactory
|
||||
{
|
||||
public:
|
||||
|
||||
virtual CommandDelegate *makeDelegate (QUndoStack& undoStack, QObject *parent) const;
|
||||
///< The ownership of the returned CommandDelegate is transferred to the caller.
|
||||
|
||||
};
|
||||
}
|
||||
#endif // RECORDSTATUSDELEGATE_H
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "../../model/world/idtableproxymodel.hpp"
|
||||
#include "../../model/world/idtable.hpp"
|
||||
#include "../../model/world/record.hpp"
|
||||
#include "recordstatusdelegate.hpp"
|
||||
|
||||
#include "util.hpp"
|
||||
|
||||
@ -80,7 +81,7 @@ std::vector<std::string> CSVWorld::Table::listDeletableSelectedIds() const
|
||||
|
||||
CSVWorld::Table::Table (const CSMWorld::UniversalId& id, CSMWorld::Data& data, QUndoStack& undoStack,
|
||||
bool createAndDelete)
|
||||
: mUndoStack (undoStack), mCreateAction (0), mEditLock (false)
|
||||
: mUndoStack (undoStack), mCreateAction (0), mEditLock (false), mRecordStatusDisplay (0)
|
||||
{
|
||||
mModel = &dynamic_cast<CSMWorld::IdTable&> (*data.getTableModel (id));
|
||||
|
||||
@ -161,6 +162,7 @@ void CSVWorld::Table::createRecord()
|
||||
|
||||
mUndoStack.push (new CSMWorld::CreateCommand (*mProxyModel, stream.str()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CSVWorld::Table::revertRecord()
|
||||
@ -201,4 +203,13 @@ void CSVWorld::Table::deleteRecord()
|
||||
mUndoStack.endMacro();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSVWorld::Table::updateEditorSetting (const QString &settingName, const QString &settingValue)
|
||||
{
|
||||
if (settingName == "Record Status Display")
|
||||
{
|
||||
dynamic_cast<CSVWorld::RecordStatusDelegate *>(this->itemDelegateForColumn(1))->updateEditorSetting (settingName, settingValue);
|
||||
emit dataChanged(mModel->index(0,1), mModel->index(mModel->rowCount()-1, 1));
|
||||
}
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ namespace CSVWorld
|
||||
CSMWorld::IdTableProxyModel *mProxyModel;
|
||||
CSMWorld::IdTable *mModel;
|
||||
bool mEditLock;
|
||||
int mRecordStatusDisplay;
|
||||
|
||||
private:
|
||||
|
||||
@ -52,6 +53,8 @@ namespace CSVWorld
|
||||
|
||||
CSMWorld::UniversalId getUniversalId (int row) const;
|
||||
|
||||
void updateEditorSetting (const QString &settingName, const QString &settingValue);
|
||||
|
||||
private slots:
|
||||
|
||||
void createRecord();
|
||||
|
@ -22,4 +22,11 @@ void CSVWorld::TableSubView::setEditLock (bool locked)
|
||||
void CSVWorld::TableSubView::rowActivated (const QModelIndex& index)
|
||||
{
|
||||
focusId (mTable->getUniversalId (index.row()));
|
||||
}
|
||||
}
|
||||
|
||||
void CSVWorld::TableSubView::updateEditorSetting(const QString &settingName, const QString &settingValue)
|
||||
{
|
||||
|
||||
if (settingName == "Record Status Display")
|
||||
mTable->updateEditorSetting(settingName, settingValue);
|
||||
}
|
||||
|
@ -23,8 +23,8 @@ namespace CSVWorld
|
||||
public:
|
||||
|
||||
TableSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document, bool createAndDelete);
|
||||
|
||||
virtual void setEditLock (bool locked);
|
||||
void updateEditorSetting (const QString &, const QString &);
|
||||
|
||||
private slots:
|
||||
|
||||
@ -32,4 +32,4 @@ namespace CSVWorld
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -82,6 +82,8 @@ namespace CSVWorld
|
||||
///< \brief Use commands instead of manipulating the model directly
|
||||
class CommandDelegate : public QStyledItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
QUndoStack& mUndoStack;
|
||||
bool mEditLock;
|
||||
|
||||
@ -105,6 +107,10 @@ namespace CSVWorld
|
||||
void setEditLock (bool locked);
|
||||
|
||||
bool isEditLocked() const;
|
||||
|
||||
private slots:
|
||||
|
||||
virtual void slotUpdateEditorSetting (const QString &settingName, const QString &settingValue) {}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@ add_openmw_dir (mwgui
|
||||
enchantingdialog trainingwindow travelwindow imagebutton exposedwindow cursor spellicons
|
||||
merchantrepair repair soulgemdialog companionwindow bookpage journalviewmodel journalbooks
|
||||
keywordsearch itemmodel containeritemmodel inventoryitemmodel sortfilteritemmodel itemview
|
||||
tradeitemmodel companionitemmodel pickpocketitemmodel
|
||||
tradeitemmodel companionitemmodel pickpocketitemmodel fontloader controllers
|
||||
)
|
||||
|
||||
add_openmw_dir (mwdialogue
|
||||
@ -106,19 +106,23 @@ target_link_libraries(openmw
|
||||
${OGRE_LIBRARIES}
|
||||
${OGRE_Terrain_LIBRARY}
|
||||
${OGRE_STATIC_PLUGINS}
|
||||
${OIS_LIBRARIES}
|
||||
${Boost_LIBRARIES}
|
||||
${OPENAL_LIBRARY}
|
||||
${SOUND_INPUT_LIBRARY}
|
||||
${BULLET_LIBRARIES}
|
||||
${MYGUI_LIBRARIES}
|
||||
${SDL2_LIBRARY}
|
||||
${MYGUI_PLATFORM_LIBRARIES}
|
||||
"shiny"
|
||||
"shiny.OgrePlatform"
|
||||
${SHINY_LIBRARIES}
|
||||
"oics"
|
||||
"sdl4ogre"
|
||||
components
|
||||
)
|
||||
|
||||
if (NOT UNIX)
|
||||
target_link_libraries(openmw ${SDL2MAIN_LIBRARY})
|
||||
endif()
|
||||
|
||||
# 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})
|
||||
@ -131,10 +135,9 @@ endif()
|
||||
|
||||
|
||||
if(APPLE)
|
||||
find_library(CARBON_FRAMEWORK Carbon)
|
||||
find_library(COCOA_FRAMEWORK Cocoa)
|
||||
find_library(IOKIT_FRAMEWORK IOKit)
|
||||
target_link_libraries(openmw ${CARBON_FRAMEWORK} ${COCOA_FRAMEWORK} ${IOKIT_FRAMEWORK})
|
||||
target_link_libraries(openmw ${COCOA_FRAMEWORK} ${IOKIT_FRAMEWORK})
|
||||
|
||||
if (FFMPEG_FOUND)
|
||||
find_library(COREVIDEO_FRAMEWORK CoreVideo)
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "engine.hpp"
|
||||
|
||||
#include "components/esm/loadcell.hpp"
|
||||
|
||||
#include <OgreRoot.h>
|
||||
@ -37,6 +38,8 @@
|
||||
#include "mwmechanics/mechanicsmanagerimp.hpp"
|
||||
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
void OMW::Engine::executeLocalScripts()
|
||||
{
|
||||
MWWorld::LocalScripts& localScripts = MWBase::Environment::get().getWorld()->getLocalScripts();
|
||||
@ -75,7 +78,8 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt)
|
||||
try
|
||||
{
|
||||
float frametime = std::min(evt.timeSinceLastFrame, 0.2f);
|
||||
mEnvironment.setFrameDuration(frametime);
|
||||
|
||||
mEnvironment.setFrameDuration (frametime);
|
||||
|
||||
// update input
|
||||
MWBase::Environment::get().getInputManager()->update(frametime, false);
|
||||
@ -129,7 +133,6 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt)
|
||||
OMW::Engine::Engine(Files::ConfigurationManager& configurationManager)
|
||||
: mOgre (0)
|
||||
, mFpsLevel(0)
|
||||
, mDebug (false)
|
||||
, mVerboseScripts (false)
|
||||
, mNewGame (false)
|
||||
, mUseSound (true)
|
||||
@ -141,6 +144,18 @@ OMW::Engine::Engine(Files::ConfigurationManager& configurationManager)
|
||||
{
|
||||
std::srand ( std::time(NULL) );
|
||||
MWClass::registerClasses();
|
||||
|
||||
Uint32 flags = SDL_INIT_VIDEO|SDL_INIT_NOPARACHUTE;
|
||||
if(SDL_WasInit(flags) == 0)
|
||||
{
|
||||
//kindly ask SDL not to trash our OGL context
|
||||
//might this be related to http://bugzilla.libsdl.org/show_bug.cgi?id=748 ?
|
||||
SDL_SetHint(SDL_HINT_RENDER_DRIVER, "software");
|
||||
if(SDL_Init(flags) != 0)
|
||||
{
|
||||
throw std::runtime_error("Could not initialize SDL! " + std::string(SDL_GetError()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OMW::Engine::~Engine()
|
||||
@ -148,6 +163,7 @@ OMW::Engine::~Engine()
|
||||
mEnvironment.cleanup();
|
||||
delete mScriptContext;
|
||||
delete mOgre;
|
||||
SDL_Quit();
|
||||
}
|
||||
|
||||
// Load BSA files
|
||||
@ -268,11 +284,6 @@ void OMW::Engine::addPlugin (const std::string& plugin)
|
||||
}
|
||||
}
|
||||
|
||||
void OMW::Engine::setDebugMode(bool debugMode)
|
||||
{
|
||||
mDebug = debugMode;
|
||||
}
|
||||
|
||||
void OMW::Engine::setScriptsVerbosity(bool scriptsVerbosity)
|
||||
{
|
||||
mVerboseScripts = scriptsVerbosity;
|
||||
@ -315,6 +326,8 @@ std::string OMW::Engine::loadSettings (Settings::Manager & settings)
|
||||
else if (boost::filesystem::exists(mCfgMgr.getGlobalPath().string() + "/transparency-overrides.cfg"))
|
||||
nifOverrides.loadTransparencyOverrides(mCfgMgr.getGlobalPath().string() + "/transparency-overrides.cfg");
|
||||
|
||||
settings.setBool("hardware cursors", "GUI", true);
|
||||
|
||||
return settingspath;
|
||||
}
|
||||
|
||||
@ -352,14 +365,16 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
|
||||
addResourcesDirectory(mResDir / "shadows");
|
||||
addZipResource(mResDir / "mygui" / "Obliviontt.zip");
|
||||
|
||||
// Create the window
|
||||
OEngine::Render::WindowSettings windowSettings;
|
||||
windowSettings.fullscreen = settings.getBool("fullscreen", "Video");
|
||||
windowSettings.window_x = settings.getInt("resolution x", "Video");
|
||||
windowSettings.window_y = settings.getInt("resolution y", "Video");
|
||||
windowSettings.screen = settings.getInt("screen", "Video");
|
||||
windowSettings.vsync = settings.getBool("vsync", "Video");
|
||||
windowSettings.icon = "openmw.png";
|
||||
std::string aa = settings.getString("antialiasing", "Video");
|
||||
windowSettings.fsaa = (aa.substr(0, 4) == "MSAA") ? aa.substr(5, aa.size()-5) : "0";
|
||||
|
||||
mOgre->createWindow("OpenMW", windowSettings);
|
||||
|
||||
loadBSA();
|
||||
@ -380,7 +395,7 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
|
||||
|
||||
mEnvironment.setWindowManager (new MWGui::WindowManager(
|
||||
mExtensions, mFpsLevel, mOgre, mCfgMgr.getLogPath().string() + std::string("/"),
|
||||
mCfgMgr.getCachePath ().string(), mScriptConsoleMode, mTranslationDataStorage));
|
||||
mCfgMgr.getCachePath ().string(), mScriptConsoleMode, mTranslationDataStorage, mEncoding));
|
||||
if (mNewGame)
|
||||
mEnvironment.getWindowManager()->setNewGame(true);
|
||||
|
||||
@ -409,7 +424,7 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
|
||||
|
||||
mEnvironment.setInputManager (new MWInput::InputManager (*mOgre,
|
||||
MWBase::Environment::get().getWorld()->getPlayer(),
|
||||
*MWBase::Environment::get().getWindowManager(), mDebug, *this, keybinderUser, keybinderUserExists));
|
||||
*MWBase::Environment::get().getWindowManager(), *this, keybinderUser, keybinderUserExists));
|
||||
|
||||
mEnvironment.getWorld()->renderPlayer();
|
||||
|
||||
|
@ -71,7 +71,6 @@ namespace OMW
|
||||
std::vector<std::string> mMaster;
|
||||
std::vector<std::string> mPlugins;
|
||||
int mFpsLevel;
|
||||
bool mDebug;
|
||||
bool mVerboseScripts;
|
||||
bool mNewGame;
|
||||
bool mUseSound;
|
||||
@ -147,10 +146,6 @@ namespace OMW
|
||||
/// Enable fps counter
|
||||
void showFPS(int level);
|
||||
|
||||
/// Enable debug mode:
|
||||
/// - non-exclusive input
|
||||
void setDebugMode(bool debugMode);
|
||||
|
||||
/// Enable or disable verbose script output
|
||||
void setScriptsVerbosity(bool scriptsVerbosity);
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include <components/files/configurationmanager.hpp>
|
||||
|
||||
#include <SDL_main.h>
|
||||
#include "engine.hpp"
|
||||
|
||||
#if defined(_WIN32) && !defined(_CONSOLE)
|
||||
@ -118,9 +119,6 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
|
||||
("anim-verbose", bpo::value<bool>()->implicit_value(true)
|
||||
->default_value(false), "output animation indices files")
|
||||
|
||||
("debug", bpo::value<bool>()->implicit_value(true)
|
||||
->default_value(false), "debug mode")
|
||||
|
||||
("nosound", bpo::value<bool>()->implicit_value(true)
|
||||
->default_value(false), "disable all sounds")
|
||||
|
||||
@ -217,8 +215,8 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
|
||||
StringsVector master = variables["master"].as<StringsVector>();
|
||||
if (master.empty())
|
||||
{
|
||||
std::cout << "No master file given. Assuming Morrowind.esm" << std::endl;
|
||||
master.push_back("Morrowind");
|
||||
std::cout << "No master file given. Aborting...\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
StringsVector plugin = variables["plugin"].as<StringsVector>();
|
||||
@ -243,7 +241,6 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
|
||||
engine.setNewGame(variables["new-game"].as<bool>());
|
||||
|
||||
// other settings
|
||||
engine.setDebugMode(variables["debug"].as<bool>());
|
||||
engine.setSoundUsage(!variables["nosound"].as<bool>());
|
||||
engine.setScriptsVerbosity(variables["script-verbose"].as<bool>());
|
||||
engine.setCompileAll(variables["script-all"].as<bool>());
|
||||
|
@ -112,6 +112,8 @@ namespace MWBase
|
||||
virtual void skipAnimation(const MWWorld::Ptr& ptr) = 0;
|
||||
///< Skip the animation for the given MW-reference for one frame. Calls to this function for
|
||||
/// references that are currently not in the scene should be ignored.
|
||||
|
||||
virtual bool checkAnimationPlaying(const MWWorld::Ptr& ptr, const std::string& groupName) = 0;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -55,6 +55,11 @@ namespace MWGui
|
||||
class DialogueWindow;
|
||||
}
|
||||
|
||||
namespace SFO
|
||||
{
|
||||
class CursorManager;
|
||||
}
|
||||
|
||||
namespace MWBase
|
||||
{
|
||||
/// \brief Interface for widnow manager (implemented in MWGui)
|
||||
@ -92,6 +97,7 @@ namespace MWBase
|
||||
virtual void updatePlayer() = 0;
|
||||
|
||||
virtual MWGui::GuiMode getMode() const = 0;
|
||||
virtual bool containsMode(MWGui::GuiMode) const = 0;
|
||||
|
||||
virtual bool isGuiMode() const = 0;
|
||||
|
||||
@ -159,7 +165,7 @@ namespace MWBase
|
||||
virtual void setFocusObject(const MWWorld::Ptr& focus) = 0;
|
||||
virtual void setFocusObjectScreenCoords(float min_x, float min_y, float max_x, float max_y) = 0;
|
||||
|
||||
virtual void setMouseVisible(bool visible) = 0;
|
||||
virtual void setCursorVisible(bool visible) = 0;
|
||||
virtual void getMousePosition(int &x, int &y) = 0;
|
||||
virtual void getMousePosition(float &x, float &y) = 0;
|
||||
virtual void setDragDrop(bool dragDrop) = 0;
|
||||
@ -258,6 +264,8 @@ namespace MWBase
|
||||
virtual void changePointer (const std::string& name) = 0;
|
||||
|
||||
virtual const Translation::Storage& getTranslationDataStorage() const = 0;
|
||||
|
||||
virtual void setKeyFocusWidget (MyGUI::Widget* widget) = 0;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -342,6 +342,10 @@ namespace MWBase
|
||||
|
||||
virtual void getContainersOwnedBy (const MWWorld::Ptr& npc, std::vector<MWWorld::Ptr>& out) = 0;
|
||||
///< get all containers in active cells owned by this Npc
|
||||
virtual void getItemsOwnedBy (const MWWorld::Ptr& npc, std::vector<MWWorld::Ptr>& out) = 0;
|
||||
///< get all items in active cells owned by this Npc
|
||||
|
||||
virtual void enableActorCollision(const MWWorld::Ptr& actor, bool enable) = 0;
|
||||
|
||||
virtual void setupExternalRendering (MWRender::ExternalRendering& rendering) = 0;
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include "../mwmechanics/creaturestats.hpp"
|
||||
#include "../mwmechanics/magiceffects.hpp"
|
||||
#include "../mwmechanics/movement.hpp"
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/mechanicsmanager.hpp"
|
||||
@ -29,6 +30,7 @@ namespace
|
||||
{
|
||||
MWMechanics::CreatureStats mCreatureStats;
|
||||
MWWorld::ContainerStore mContainerStore;
|
||||
MWMechanics::Movement mMovement;
|
||||
|
||||
virtual MWWorld::CustomData *clone() const;
|
||||
};
|
||||
@ -47,6 +49,18 @@ namespace MWClass
|
||||
{
|
||||
std::auto_ptr<CustomData> data (new CustomData);
|
||||
|
||||
static bool inited = false;
|
||||
if(!inited)
|
||||
{
|
||||
const MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||
const MWWorld::Store<ESM::GameSetting> &gmst = world->getStore().get<ESM::GameSetting>();
|
||||
|
||||
fMinWalkSpeedCreature = gmst.find("fMinWalkSpeedCreature");
|
||||
fMaxWalkSpeedCreature = gmst.find("fMaxWalkSpeedCreature");
|
||||
|
||||
inited = true;
|
||||
}
|
||||
|
||||
MWWorld::LiveCellRef<ESM::Creature> *ref = ptr.get<ESM::Creature>();
|
||||
|
||||
// creature stats
|
||||
@ -181,6 +195,42 @@ namespace MWClass
|
||||
return true;
|
||||
}
|
||||
|
||||
float Creature::getSpeed(const MWWorld::Ptr &ptr) const
|
||||
{
|
||||
MWMechanics::CreatureStats& stats = getCreatureStats(ptr);
|
||||
float walkSpeed = fMinWalkSpeedCreature->getFloat() + 0.01 * stats.getAttribute(ESM::Attribute::Speed).getModified()
|
||||
* (fMaxWalkSpeedCreature->getFloat() - fMinWalkSpeedCreature->getFloat());
|
||||
/// \todo what about the rest?
|
||||
return walkSpeed;
|
||||
}
|
||||
|
||||
MWMechanics::Movement& Creature::getMovementSettings (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ensureCustomData (ptr);
|
||||
|
||||
return dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mMovement;
|
||||
}
|
||||
|
||||
Ogre::Vector3 Creature::getMovementVector (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
MWMechanics::Movement &movement = getMovementSettings(ptr);
|
||||
Ogre::Vector3 vec(movement.mPosition);
|
||||
movement.mPosition[0] = 0.0f;
|
||||
movement.mPosition[1] = 0.0f;
|
||||
movement.mPosition[2] = 0.0f;
|
||||
return vec;
|
||||
}
|
||||
|
||||
Ogre::Vector3 Creature::getRotationVector (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
MWMechanics::Movement &movement = getMovementSettings(ptr);
|
||||
Ogre::Vector3 vec(movement.mRotation);
|
||||
movement.mRotation[0] = 0.0f;
|
||||
movement.mRotation[1] = 0.0f;
|
||||
movement.mRotation[2] = 0.0f;
|
||||
return vec;
|
||||
}
|
||||
|
||||
MWGui::ToolTipInfo Creature::getToolTipInfo (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::Creature> *ref =
|
||||
@ -249,4 +299,7 @@ namespace MWClass
|
||||
|
||||
return MWWorld::Ptr(&cell.mCreatures.insert(*ref), &cell);
|
||||
}
|
||||
|
||||
const ESM::GameSetting* Creature::fMinWalkSpeedCreature;
|
||||
const ESM::GameSetting* Creature::fMaxWalkSpeedCreature;
|
||||
}
|
||||
|
@ -12,6 +12,9 @@ namespace MWClass
|
||||
virtual MWWorld::Ptr
|
||||
copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const;
|
||||
|
||||
static const ESM::GameSetting *fMinWalkSpeedCreature;
|
||||
static const ESM::GameSetting *fMaxWalkSpeedCreature;
|
||||
|
||||
public:
|
||||
|
||||
virtual std::string getId (const MWWorld::Ptr& ptr) const;
|
||||
@ -66,6 +69,18 @@ namespace MWClass
|
||||
|
||||
virtual bool isPersistent (const MWWorld::Ptr& ptr) const;
|
||||
|
||||
virtual MWMechanics::Movement& getMovementSettings (const MWWorld::Ptr& ptr) const;
|
||||
///< Return desired movement.
|
||||
|
||||
virtual Ogre::Vector3 getMovementVector (const MWWorld::Ptr& ptr) const;
|
||||
///< Return desired movement vector (determined based on movement settings,
|
||||
/// stance and stats).
|
||||
|
||||
virtual Ogre::Vector3 getRotationVector (const MWWorld::Ptr& ptr) const;
|
||||
///< Return desired rotations, as euler angles.
|
||||
|
||||
float getSpeed (const MWWorld::Ptr& ptr) const;
|
||||
|
||||
static void registerSelf();
|
||||
|
||||
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
||||
|
@ -223,6 +223,9 @@ struct TypesetBookImpl::Typesetter : BookTypesetter
|
||||
|
||||
Style * createStyle (char const * fontName, Colour fontColour)
|
||||
{
|
||||
if (strcmp(fontName, "") == 0)
|
||||
return createStyle(MyGUI::FontManager::getInstance().getDefaultFont().c_str(), fontColour);
|
||||
|
||||
for (Styles::iterator i = mBook->mStyles.begin (); i != mBook->mStyles.end (); ++i)
|
||||
if (i->match (fontName, fontColour, fontColour, fontColour, 0))
|
||||
return &*i;
|
||||
@ -405,7 +408,8 @@ struct TypesetBookImpl::Typesetter : BookTypesetter
|
||||
while (!stream.eof () && !ucsLineBreak (stream.peek ()) && ucsBreakingSpace (stream.peek ()))
|
||||
{
|
||||
MyGUI::GlyphInfo* gi = style->mFont->getGlyphInfo (stream.peek ());
|
||||
space_width += gi->advance;
|
||||
if (gi)
|
||||
space_width += gi->advance + gi->bearingX;
|
||||
stream.consume ();
|
||||
}
|
||||
|
||||
@ -414,7 +418,8 @@ struct TypesetBookImpl::Typesetter : BookTypesetter
|
||||
while (!stream.eof () && !ucsLineBreak (stream.peek ()) && !ucsBreakingSpace (stream.peek ()))
|
||||
{
|
||||
MyGUI::GlyphInfo* gi = style->mFont->getGlyphInfo (stream.peek ());
|
||||
word_width += gi->advance + gi->bearingX;
|
||||
if (gi)
|
||||
word_width += gi->advance + gi->bearingX;
|
||||
word_height = line_height;
|
||||
++character_count;
|
||||
stream.consume ();
|
||||
@ -628,6 +633,9 @@ namespace
|
||||
{
|
||||
MyGUI::GlyphInfo* gi = mFont->getGlyphInfo (ch);
|
||||
|
||||
if (!gi)
|
||||
return;
|
||||
|
||||
MyGUI::FloatRect vr;
|
||||
|
||||
vr.left = mCursor.left + gi->bearingX;
|
||||
@ -647,7 +655,8 @@ namespace
|
||||
{
|
||||
MyGUI::GlyphInfo* gi = mFont->getGlyphInfo (ch);
|
||||
|
||||
mCursor.left += gi->bearingX + gi->advance;
|
||||
if (gi)
|
||||
mCursor.left += gi->bearingX + gi->advance;
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -130,26 +130,12 @@ namespace MWGui
|
||||
|
||||
void BookWindow::onNextPageButtonClicked (MyGUI::Widget* sender)
|
||||
{
|
||||
if ((mCurrentPage+1)*2 < mPages.size())
|
||||
{
|
||||
MWBase::Environment::get().getSoundManager()->playSound ("book page2", 1.0, 1.0);
|
||||
|
||||
++mCurrentPage;
|
||||
|
||||
updatePages();
|
||||
}
|
||||
nextPage();
|
||||
}
|
||||
|
||||
void BookWindow::onPrevPageButtonClicked (MyGUI::Widget* sender)
|
||||
{
|
||||
if (mCurrentPage > 0)
|
||||
{
|
||||
MWBase::Environment::get().getSoundManager()->playSound ("book page", 1.0, 1.0);
|
||||
|
||||
--mCurrentPage;
|
||||
|
||||
updatePages();
|
||||
}
|
||||
prevPage();
|
||||
}
|
||||
|
||||
void BookWindow::updatePages()
|
||||
@ -194,5 +180,28 @@ namespace MWGui
|
||||
if (button->getAlign().isRight())
|
||||
button->setPosition(button->getPosition() + MyGUI::IntPoint(diff.width,0));
|
||||
}
|
||||
|
||||
void BookWindow::nextPage()
|
||||
{
|
||||
if ((mCurrentPage+1)*2 < mPages.size())
|
||||
{
|
||||
MWBase::Environment::get().getSoundManager()->playSound ("book page2", 1.0, 1.0);
|
||||
|
||||
++mCurrentPage;
|
||||
|
||||
updatePages();
|
||||
}
|
||||
}
|
||||
void BookWindow::prevPage()
|
||||
{
|
||||
if (mCurrentPage > 0)
|
||||
{
|
||||
MWBase::Environment::get().getSoundManager()->playSound ("book page", 1.0, 1.0);
|
||||
|
||||
--mCurrentPage;
|
||||
|
||||
updatePages();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,7 +16,8 @@ namespace MWGui
|
||||
|
||||
void open(MWWorld::Ptr book);
|
||||
void setTakeButtonShow(bool show);
|
||||
|
||||
void nextPage();
|
||||
void prevPage();
|
||||
void setInventoryAllowed(bool allowed);
|
||||
|
||||
protected:
|
||||
|
@ -238,6 +238,12 @@ namespace MWGui
|
||||
}
|
||||
}
|
||||
|
||||
void CharacterCreation::doRenderUpdate()
|
||||
{
|
||||
if (mRaceDialog)
|
||||
mRaceDialog->doRenderUpdate();
|
||||
}
|
||||
|
||||
void CharacterCreation::setPlayerHealth (const MWMechanics::DynamicStat<float>& value)
|
||||
{
|
||||
mPlayerHealth = value;
|
||||
|
@ -41,6 +41,7 @@ namespace MWGui
|
||||
void setValue (const std::string& id, const MWMechanics::DynamicStat<float>& value);
|
||||
void setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::Stat<float>& value);
|
||||
void configureSkills (const SkillList& major, const SkillList& minor);
|
||||
void doRenderUpdate();
|
||||
|
||||
private:
|
||||
//Dialogs
|
||||
|
@ -407,7 +407,7 @@ namespace MWGui
|
||||
getWidget(mEditName, "EditName");
|
||||
|
||||
// Make sure the edit box has focus
|
||||
MyGUI::InputManager::getInstance().setKeyFocusWidget(mEditName);
|
||||
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mEditName);
|
||||
|
||||
MyGUI::Button* descriptionButton;
|
||||
getWidget(descriptionButton, "DescriptionButton");
|
||||
@ -866,7 +866,7 @@ namespace MWGui
|
||||
okButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sInputMenu1", ""));
|
||||
|
||||
// Make sure the edit box has focus
|
||||
MyGUI::InputManager::getInstance().setKeyFocusWidget(mTextEdit);
|
||||
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mTextEdit);
|
||||
}
|
||||
|
||||
DescriptionDialog::~DescriptionDialog()
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "../mwscript/extensions.hpp"
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/windowmanager.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
@ -131,16 +132,12 @@ namespace MWGui
|
||||
|
||||
// Give keyboard focus to the combo box whenever the console is
|
||||
// turned on
|
||||
MyGUI::InputManager::getInstance().setKeyFocusWidget(command);
|
||||
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(command);
|
||||
}
|
||||
|
||||
void Console::disable()
|
||||
{
|
||||
setVisible(false);
|
||||
setSelectedObject(MWWorld::Ptr());
|
||||
// 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)
|
||||
@ -415,7 +412,7 @@ namespace MWGui
|
||||
setTitle("#{sConsoleTitle}");
|
||||
mPtr = MWWorld::Ptr();
|
||||
}
|
||||
MyGUI::InputManager::getInstance().setKeyFocusWidget(command);
|
||||
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(command);
|
||||
}
|
||||
|
||||
void Console::onReferenceUnavailable()
|
||||
|
@ -3,11 +3,39 @@
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
|
||||
#include "../mwbase/world.hpp"
|
||||
#include "../mwbase/environment.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
bool stacks (const MWWorld::Ptr& left, const MWWorld::Ptr& right)
|
||||
{
|
||||
if (left == right)
|
||||
return true;
|
||||
|
||||
// If one of the items is in an inventory and currently equipped, we need to check stacking both ways to be sure
|
||||
if (left.getContainerStore() && right.getContainerStore())
|
||||
return left.getContainerStore()->stacks(left, right)
|
||||
&& right.getContainerStore()->stacks(left, right);
|
||||
|
||||
if (left.getContainerStore())
|
||||
return left.getContainerStore()->stacks(left, right);
|
||||
if (right.getContainerStore())
|
||||
return right.getContainerStore()->stacks(left, right);
|
||||
|
||||
MWWorld::ContainerStore store;
|
||||
return store.stacks(left, right);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
ContainerItemModel::ContainerItemModel(const std::vector<MWWorld::Ptr>& itemSources)
|
||||
ContainerItemModel::ContainerItemModel(const std::vector<MWWorld::Ptr>& itemSources, const std::vector<MWWorld::Ptr>& worldItems)
|
||||
: mItemSources(itemSources)
|
||||
, mWorldItems(worldItems)
|
||||
{
|
||||
assert (mItemSources.size());
|
||||
}
|
||||
@ -65,8 +93,7 @@ void ContainerItemModel::removeItem (const ItemStack& item, size_t count)
|
||||
|
||||
for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it)
|
||||
{
|
||||
// If one of the items is in an inventory and currently equipped, we need to check stacking both ways to be sure
|
||||
if (*it == item.mBase || (store.stacks(*it, item.mBase) && item.mBase.getContainerStore()->stacks(*it, item.mBase)))
|
||||
if (stacks(*it, item.mBase))
|
||||
{
|
||||
int refCount = it->getRefData().getCount();
|
||||
it->getRefData().setCount(std::max(0, refCount - toRemove));
|
||||
@ -76,6 +103,21 @@ void ContainerItemModel::removeItem (const ItemStack& item, size_t count)
|
||||
}
|
||||
}
|
||||
}
|
||||
for (std::vector<MWWorld::Ptr>::iterator source = mWorldItems.begin(); source != mWorldItems.end(); ++source)
|
||||
{
|
||||
if (stacks(*source, item.mBase))
|
||||
{
|
||||
int refCount = source->getRefData().getCount();
|
||||
if (refCount - toRemove <= 0)
|
||||
MWBase::Environment::get().getWorld()->deleteObject(*source);
|
||||
else
|
||||
source->getRefData().setCount(std::max(0, refCount - toRemove));
|
||||
toRemove -= refCount;
|
||||
if (toRemove <= 0)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
throw std::runtime_error("Not enough items to remove could be found");
|
||||
}
|
||||
|
||||
@ -91,8 +133,7 @@ void ContainerItemModel::update()
|
||||
std::vector<ItemStack>::iterator itemStack = mItems.begin();
|
||||
for (; itemStack != mItems.end(); ++itemStack)
|
||||
{
|
||||
// If one of the items is in an inventory and currently equipped, we need to check stacking both ways to be sure
|
||||
if (store.stacks(itemStack->mBase, *it) && it->getContainerStore()->stacks(itemStack->mBase, *it))
|
||||
if (stacks(*it, itemStack->mBase))
|
||||
{
|
||||
// we already have an item stack of this kind, add to it
|
||||
itemStack->mCount += it->getRefData().getCount();
|
||||
@ -108,6 +149,26 @@ void ContainerItemModel::update()
|
||||
}
|
||||
}
|
||||
}
|
||||
for (std::vector<MWWorld::Ptr>::iterator source = mWorldItems.begin(); source != mWorldItems.end(); ++source)
|
||||
{
|
||||
std::vector<ItemStack>::iterator itemStack = mItems.begin();
|
||||
for (; itemStack != mItems.end(); ++itemStack)
|
||||
{
|
||||
if (stacks(*source, itemStack->mBase))
|
||||
{
|
||||
// we already have an item stack of this kind, add to it
|
||||
itemStack->mCount += source->getRefData().getCount();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (itemStack == mItems.end())
|
||||
{
|
||||
// no stack yet, create one
|
||||
ItemStack newItem (*source, this, source->getRefData().getCount());
|
||||
mItems.push_back(newItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ namespace MWGui
|
||||
class ContainerItemModel : public ItemModel
|
||||
{
|
||||
public:
|
||||
ContainerItemModel (const std::vector<MWWorld::Ptr>& itemSources);
|
||||
ContainerItemModel (const std::vector<MWWorld::Ptr>& itemSources, const std::vector<MWWorld::Ptr>& worldItems);
|
||||
///< @note The order of elements \a itemSources matters here. The first element has the highest priority for removal,
|
||||
/// while the last element will be used to add new items to.
|
||||
|
||||
@ -28,6 +28,7 @@ namespace MWGui
|
||||
|
||||
private:
|
||||
std::vector<MWWorld::Ptr> mItemSources;
|
||||
std::vector<MWWorld::Ptr> mWorldItems;
|
||||
|
||||
std::vector<ItemStack> mItems;
|
||||
};
|
||||
|
54
apps/openmw/mwgui/controllers.cpp
Normal file
54
apps/openmw/mwgui/controllers.cpp
Normal file
@ -0,0 +1,54 @@
|
||||
#include "controllers.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
namespace Controllers
|
||||
{
|
||||
|
||||
ControllerRepeatClick::ControllerRepeatClick() :
|
||||
mInit(0.5),
|
||||
mStep(0.1),
|
||||
mEnabled(true),
|
||||
mTimeLeft(0)
|
||||
{
|
||||
}
|
||||
|
||||
ControllerRepeatClick::~ControllerRepeatClick()
|
||||
{
|
||||
}
|
||||
|
||||
bool ControllerRepeatClick::addTime(MyGUI::Widget* _widget, float _time)
|
||||
{
|
||||
if(mTimeLeft == 0)
|
||||
mTimeLeft = mInit;
|
||||
|
||||
mTimeLeft -= _time;
|
||||
while (mTimeLeft <= 0)
|
||||
{
|
||||
mTimeLeft += mStep;
|
||||
eventRepeatClick(_widget, this);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void ControllerRepeatClick::setRepeat(float init, float step)
|
||||
{
|
||||
mInit = init;
|
||||
mStep = step;
|
||||
}
|
||||
|
||||
void ControllerRepeatClick::setEnabled(bool enable)
|
||||
{
|
||||
mEnabled = enable;
|
||||
}
|
||||
|
||||
void ControllerRepeatClick::setProperty(const std::string& _key, const std::string& _value)
|
||||
{
|
||||
}
|
||||
|
||||
void ControllerRepeatClick::prepareItem(MyGUI::Widget* _widget)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
}
|
46
apps/openmw/mwgui/controllers.hpp
Normal file
46
apps/openmw/mwgui/controllers.hpp
Normal file
@ -0,0 +1,46 @@
|
||||
#ifndef MWGUI_CONTROLLERS_H
|
||||
#define MWGUI_CONTROLLERS_H
|
||||
|
||||
#include <MyGUI_Widget.h>
|
||||
#include <MyGUI_ControllerItem.h>
|
||||
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
namespace Controllers
|
||||
{
|
||||
class ControllerRepeatClick :
|
||||
public MyGUI::ControllerItem
|
||||
{
|
||||
MYGUI_RTTI_DERIVED( ControllerRepeatClick )
|
||||
|
||||
public:
|
||||
ControllerRepeatClick();
|
||||
virtual ~ControllerRepeatClick();
|
||||
|
||||
void setRepeat(float init, float step);
|
||||
void setEnabled(bool enable);
|
||||
virtual void setProperty(const std::string& _key, const std::string& _value);
|
||||
|
||||
// Events
|
||||
typedef MyGUI::delegates::CMultiDelegate2<MyGUI::Widget*, MyGUI::ControllerItem*> EventHandle_RepeatClickVoid;
|
||||
|
||||
/** Event : Repeat Click.\n
|
||||
signature : void method(MyGUI::Widget* _sender, MyGUI::ControllerItem *_controller)\n
|
||||
*/
|
||||
EventHandle_RepeatClickVoid eventRepeatClick;
|
||||
|
||||
private:
|
||||
bool addTime(MyGUI::Widget* _widget, float _time);
|
||||
void prepareItem(MyGUI::Widget* _widget);
|
||||
|
||||
private:
|
||||
float mInit;
|
||||
float mStep;
|
||||
bool mEnabled;
|
||||
float mTimeLeft;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -2,6 +2,9 @@
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/windowmanager.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
CountDialog::CountDialog() :
|
||||
@ -40,7 +43,7 @@ namespace MWGui
|
||||
mMainWidget->getHeight());
|
||||
|
||||
// by default, the text edit field has the focus of the keyboard
|
||||
MyGUI::InputManager::getInstance().setKeyFocusWidget(mItemEdit);
|
||||
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mItemEdit);
|
||||
|
||||
mSlider->setScrollPosition(maxCount-1);
|
||||
mItemEdit->setCaption(boost::lexical_cast<std::string>(maxCount));
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "../mwbase/windowmanager.hpp"
|
||||
#include "../mwbase/mechanicsmanager.hpp"
|
||||
#include "../mwbase/world.hpp"
|
||||
#include "../mwbase/soundmanager.hpp"
|
||||
|
||||
#include "../mwmechanics/npcstats.hpp"
|
||||
|
||||
@ -115,7 +116,7 @@ namespace MWGui
|
||||
|
||||
void Response::write(BookTypesetter::Ptr typesetter, KeywordSearchT* keywordSearch, std::map<std::string, Link*>& topicLinks) const
|
||||
{
|
||||
BookTypesetter::Style* title = typesetter->createStyle("EB Garamond", MyGUI::Colour(223/255.f, 201/255.f, 159/255.f));
|
||||
BookTypesetter::Style* title = typesetter->createStyle("", MyGUI::Colour(223/255.f, 201/255.f, 159/255.f));
|
||||
typesetter->sectionBreak(9);
|
||||
if (mTitle != "")
|
||||
typesetter->write(title, to_utf8_span(mTitle.c_str()));
|
||||
@ -159,7 +160,7 @@ namespace MWGui
|
||||
|
||||
if (hyperLinks.size() && MWBase::Environment::get().getWindowManager()->getTranslationDataStorage().hasTranslation())
|
||||
{
|
||||
BookTypesetter::Style* style = typesetter->createStyle("EB Garamond", MyGUI::Colour(202/255.f, 165/255.f, 96/255.f));
|
||||
BookTypesetter::Style* style = typesetter->createStyle("", MyGUI::Colour(202/255.f, 165/255.f, 96/255.f));
|
||||
size_t formatted = 0; // points to the first character that is not laid out yet
|
||||
for (std::map<Range, intptr_t>::iterator it = hyperLinks.begin(); it != hyperLinks.end(); ++it)
|
||||
{
|
||||
@ -197,7 +198,7 @@ namespace MWGui
|
||||
|
||||
void Response::addTopicLink(BookTypesetter::Ptr typesetter, intptr_t topicId, size_t begin, size_t end) const
|
||||
{
|
||||
BookTypesetter::Style* style = typesetter->createStyle("EB Garamond", MyGUI::Colour(202/255.f, 165/255.f, 96/255.f));
|
||||
BookTypesetter::Style* style = typesetter->createStyle("", MyGUI::Colour(202/255.f, 165/255.f, 96/255.f));
|
||||
|
||||
const MyGUI::Colour linkHot (143/255.f, 155/255.f, 218/255.f);
|
||||
const MyGUI::Colour linkNormal (112/255.f, 126/255.f, 207/255.f);
|
||||
@ -215,7 +216,7 @@ namespace MWGui
|
||||
|
||||
void Message::write(BookTypesetter::Ptr typesetter, KeywordSearchT* keywordSearch, std::map<std::string, Link*>& topicLinks) const
|
||||
{
|
||||
BookTypesetter::Style* title = typesetter->createStyle("EB Garamond", MyGUI::Colour(223/255.f, 201/255.f, 159/255.f));
|
||||
BookTypesetter::Style* title = typesetter->createStyle("", MyGUI::Colour(223/255.f, 201/255.f, 159/255.f));
|
||||
typesetter->sectionBreak(9);
|
||||
typesetter->write(title, to_utf8_span(mText.c_str()));
|
||||
}
|
||||
@ -224,16 +225,22 @@ namespace MWGui
|
||||
|
||||
void Choice::activated()
|
||||
{
|
||||
|
||||
MWBase::Environment::get().getSoundManager()->playSound("Menu Click", 1.0, 1.0);
|
||||
MWBase::Environment::get().getDialogueManager()->questionAnswered(mChoiceId);
|
||||
}
|
||||
|
||||
void Topic::activated()
|
||||
{
|
||||
|
||||
MWBase::Environment::get().getSoundManager()->playSound("Menu Click", 1.f, 1.f);
|
||||
MWBase::Environment::get().getDialogueManager()->keywordSelected(Misc::StringUtils::lowerCase(mTopicId));
|
||||
}
|
||||
|
||||
void Goodbye::activated()
|
||||
{
|
||||
|
||||
MWBase::Environment::get().getSoundManager()->playSound("Menu Click", 1.f, 1.f);
|
||||
MWBase::Environment::get().getDialogueManager()->goodbyeSelected();
|
||||
}
|
||||
|
||||
@ -465,13 +472,14 @@ namespace MWGui
|
||||
(*it)->write(typesetter, &mKeywordSearch, mTopicLinks);
|
||||
|
||||
|
||||
BookTypesetter::Style* body = typesetter->createStyle("EB Garamond", MyGUI::Colour::White);
|
||||
BookTypesetter::Style* body = typesetter->createStyle("", MyGUI::Colour::White);
|
||||
|
||||
typesetter->sectionBreak(9);
|
||||
// choices
|
||||
const MyGUI::Colour linkHot (223/255.f, 201/255.f, 159/255.f);
|
||||
const MyGUI::Colour linkNormal (150/255.f, 50/255.f, 30/255.f);
|
||||
const MyGUI::Colour linkActive (243/255.f, 237/255.f, 221/255.f);
|
||||
for (std::map<std::string, int>::iterator it = mChoices.begin(); it != mChoices.end(); ++it)
|
||||
for (std::map<std::string, int>::reverse_iterator it = mChoices.rbegin(); it != mChoices.rend(); ++it)
|
||||
{
|
||||
Choice* link = new Choice(it->second);
|
||||
mLinks.push_back(link);
|
||||
|
@ -61,30 +61,32 @@ namespace MWGui
|
||||
void EnchantingDialog::updateLabels()
|
||||
{
|
||||
std::stringstream enchantCost;
|
||||
enchantCost << std::setprecision(1) << std::fixed << mEnchanting.getEnchantCost();
|
||||
enchantCost << std::setprecision(1) << std::fixed << mEnchanting.getEnchantPoints();
|
||||
mEnchantmentPoints->setCaption(enchantCost.str() + " / " + boost::lexical_cast<std::string>(mEnchanting.getMaxEnchantValue()));
|
||||
|
||||
mCharge->setCaption(boost::lexical_cast<std::string>(mEnchanting.getGemCharge()));
|
||||
|
||||
mCastCost->setCaption(boost::lexical_cast<std::string>(mEnchanting.getEnchantCost()));
|
||||
std::stringstream castCost;
|
||||
castCost << std::setprecision(1) << std::fixed << mEnchanting.getCastCost();
|
||||
mCastCost->setCaption(boost::lexical_cast<std::string>(castCost.str()));
|
||||
|
||||
mPrice->setCaption(boost::lexical_cast<std::string>(mEnchanting.getEnchantPrice()));
|
||||
|
||||
switch(mEnchanting.getEnchantType())
|
||||
switch(mEnchanting.getCastStyle())
|
||||
{
|
||||
case 0:
|
||||
case ESM::Enchantment::CastOnce:
|
||||
mTypeButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sItemCastOnce","Cast Once"));
|
||||
mAddEffectDialog.constantEffect=false;
|
||||
break;
|
||||
case 1:
|
||||
case ESM::Enchantment::WhenStrikes:
|
||||
mTypeButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sItemCastWhenStrikes", "When Strikes"));
|
||||
mAddEffectDialog.constantEffect=false;
|
||||
break;
|
||||
case 2:
|
||||
case ESM::Enchantment::WhenUsed:
|
||||
mTypeButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sItemCastWhenUsed", "When Used"));
|
||||
mAddEffectDialog.constantEffect=false;
|
||||
break;
|
||||
case 3:
|
||||
case ESM::Enchantment::ConstantEffect:
|
||||
mTypeButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sItemCastConstant", "Cast Constant"));
|
||||
mAddEffectDialog.constantEffect=true;
|
||||
break;
|
||||
@ -169,7 +171,7 @@ namespace MWGui
|
||||
image->eventMouseButtonClick += MyGUI::newDelegate(this, &EnchantingDialog::onRemoveItem);
|
||||
|
||||
mEnchanting.setOldItem(item);
|
||||
mEnchanting.nextEnchantType();
|
||||
mEnchanting.nextCastStyle();
|
||||
updateLabels();
|
||||
}
|
||||
|
||||
@ -248,7 +250,7 @@ namespace MWGui
|
||||
|
||||
void EnchantingDialog::onTypeButtonClicked(MyGUI::Widget* sender)
|
||||
{
|
||||
mEnchanting.nextEnchantType();
|
||||
mEnchanting.nextCastStyle();
|
||||
updateLabels();
|
||||
}
|
||||
|
||||
@ -278,7 +280,7 @@ namespace MWGui
|
||||
return;
|
||||
}
|
||||
|
||||
if (mEnchanting.getEnchantCost() > mEnchanting.getMaxEnchantValue())
|
||||
if (mEnchanting.getEnchantPoints() > mEnchanting.getMaxEnchantValue())
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage29}");
|
||||
return;
|
||||
|
238
apps/openmw/mwgui/fontloader.cpp
Normal file
238
apps/openmw/mwgui/fontloader.cpp
Normal file
@ -0,0 +1,238 @@
|
||||
#include "fontloader.hpp"
|
||||
|
||||
#include <OgreResourceGroupManager.h>
|
||||
#include <OgreTextureManager.h>
|
||||
|
||||
#include <MyGUI_ResourceManager.h>
|
||||
#include <MyGUI_FontManager.h>
|
||||
#include <MyGUI_ResourceManualFont.h>
|
||||
#include <MyGUI_XmlDocument.h>
|
||||
#include <MyGUI_FactoryManager.h>
|
||||
|
||||
#include <components/misc/stringops.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
unsigned long utf8ToUnicode(const std::string& utf8)
|
||||
{
|
||||
size_t i = 0;
|
||||
unsigned long unicode;
|
||||
size_t todo;
|
||||
unsigned char ch = utf8[i++];
|
||||
if (ch <= 0x7F)
|
||||
{
|
||||
unicode = ch;
|
||||
todo = 0;
|
||||
}
|
||||
else if (ch <= 0xBF)
|
||||
{
|
||||
throw std::logic_error("not a UTF-8 string");
|
||||
}
|
||||
else if (ch <= 0xDF)
|
||||
{
|
||||
unicode = ch&0x1F;
|
||||
todo = 1;
|
||||
}
|
||||
else if (ch <= 0xEF)
|
||||
{
|
||||
unicode = ch&0x0F;
|
||||
todo = 2;
|
||||
}
|
||||
else if (ch <= 0xF7)
|
||||
{
|
||||
unicode = ch&0x07;
|
||||
todo = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::logic_error("not a UTF-8 string");
|
||||
}
|
||||
for (size_t j = 0; j < todo; ++j)
|
||||
{
|
||||
unsigned char ch = utf8[i++];
|
||||
if (ch < 0x80 || ch > 0xBF)
|
||||
throw std::logic_error("not a UTF-8 string");
|
||||
unicode <<= 6;
|
||||
unicode += ch & 0x3F;
|
||||
}
|
||||
if (unicode >= 0xD800 && unicode <= 0xDFFF)
|
||||
throw std::logic_error("not a UTF-8 string");
|
||||
if (unicode > 0x10FFFF)
|
||||
throw std::logic_error("not a UTF-8 string");
|
||||
|
||||
return unicode;
|
||||
}
|
||||
}
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
FontLoader::FontLoader(ToUTF8::FromType encoding)
|
||||
{
|
||||
if (encoding == ToUTF8::WINDOWS_1252)
|
||||
mEncoding = ToUTF8::CP437;
|
||||
else
|
||||
mEncoding = encoding;
|
||||
}
|
||||
|
||||
void FontLoader::loadAllFonts()
|
||||
{
|
||||
Ogre::StringVector groups = Ogre::ResourceGroupManager::getSingleton().getResourceGroups ();
|
||||
for (Ogre::StringVector::iterator it = groups.begin(); it != groups.end(); ++it)
|
||||
{
|
||||
Ogre::StringVectorPtr resourcesInThisGroup = Ogre::ResourceGroupManager::getSingleton ().findResourceNames (*it, "*.fnt");
|
||||
for (Ogre::StringVector::iterator resource = resourcesInThisGroup->begin(); resource != resourcesInThisGroup->end(); ++resource)
|
||||
{
|
||||
loadFont(*resource);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
} Point;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float u1; // appears unused, always 0
|
||||
Point top_left;
|
||||
Point top_right;
|
||||
Point bottom_left;
|
||||
Point bottom_right;
|
||||
float width;
|
||||
float height;
|
||||
float u2; // appears unused, always 0
|
||||
float kerning;
|
||||
float ascent;
|
||||
} GlyphInfo;
|
||||
|
||||
void FontLoader::loadFont(const std::string &fileName)
|
||||
{
|
||||
Ogre::DataStreamPtr file = Ogre::ResourceGroupManager::getSingleton().openResource(fileName);
|
||||
|
||||
float fontSize;
|
||||
int one;
|
||||
file->read(&fontSize, sizeof(fontSize));
|
||||
|
||||
file->read(&one, sizeof(int));
|
||||
assert(one == 1);
|
||||
file->read(&one, sizeof(int));
|
||||
assert(one == 1);
|
||||
|
||||
char name_[284];
|
||||
file->read(name_, sizeof(name_));
|
||||
std::string name(name_);
|
||||
|
||||
GlyphInfo data[256];
|
||||
file->read(data, sizeof(data));
|
||||
file->close();
|
||||
|
||||
// Create the font texture
|
||||
std::string bitmapFilename = "Fonts/" + std::string(name) + ".tex";
|
||||
Ogre::DataStreamPtr bitmapFile = Ogre::ResourceGroupManager::getSingleton().openResource(bitmapFilename);
|
||||
|
||||
int width, height;
|
||||
bitmapFile->read(&width, sizeof(int));
|
||||
bitmapFile->read(&height, sizeof(int));
|
||||
|
||||
std::vector<Ogre::uchar> textureData;
|
||||
textureData.resize(width*height*4);
|
||||
bitmapFile->read(&textureData[0], width*height*4);
|
||||
bitmapFile->close();
|
||||
|
||||
std::string textureName = name;
|
||||
Ogre::Image image;
|
||||
image.loadDynamicImage(&textureData[0], width, height, Ogre::PF_BYTE_RGBA);
|
||||
Ogre::TexturePtr texture = Ogre::TextureManager::getSingleton().createManual(textureName,
|
||||
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
|
||||
Ogre::TEX_TYPE_2D,
|
||||
width, height, 0, Ogre::PF_BYTE_RGBA);
|
||||
texture->loadImage(image);
|
||||
|
||||
// Register the font with MyGUI
|
||||
MyGUI::ResourceManualFont* font = static_cast<MyGUI::ResourceManualFont*>(
|
||||
MyGUI::FactoryManager::getInstance().createObject("Resource", "ResourceManualFont"));
|
||||
// We need to emulate loading from XML because the data members are private as of mygui 3.2.0
|
||||
MyGUI::xml::Document xmlDocument;
|
||||
MyGUI::xml::ElementPtr root = xmlDocument.createRoot("ResourceManualFont");
|
||||
|
||||
if (name.size() >= 5 && Misc::StringUtils::ciEqual(name.substr(0, 5), "magic"))
|
||||
root->addAttribute("name", "Magic Cards");
|
||||
else if (name.size() >= 7 && Misc::StringUtils::ciEqual(name.substr(0, 7), "century"))
|
||||
root->addAttribute("name", "Century Gothic");
|
||||
else if (name.size() >= 7 && Misc::StringUtils::ciEqual(name.substr(0, 7), "daedric"))
|
||||
root->addAttribute("name", "Daedric");
|
||||
else
|
||||
return; // no point in loading it, since there is no way of using additional fonts
|
||||
|
||||
MyGUI::xml::ElementPtr defaultHeight = root->createChild("Property");
|
||||
defaultHeight->addAttribute("key", "DefaultHeight");
|
||||
defaultHeight->addAttribute("value", fontSize);
|
||||
MyGUI::xml::ElementPtr source = root->createChild("Property");
|
||||
source->addAttribute("key", "Source");
|
||||
source->addAttribute("value", std::string(textureName));
|
||||
MyGUI::xml::ElementPtr codes = root->createChild("Codes");
|
||||
|
||||
for(int i = 0; i < 256; i++)
|
||||
{
|
||||
int x1 = data[i].top_left.x*width;
|
||||
int y1 = data[i].top_left.y*height;
|
||||
int w = data[i].top_right.x*width - x1;
|
||||
int h = data[i].bottom_left.y*height - y1;
|
||||
|
||||
ToUTF8::Utf8Encoder encoder(mEncoding);
|
||||
unsigned long unicodeVal = utf8ToUnicode(encoder.getUtf8(std::string(1, (unsigned char)(i))));
|
||||
|
||||
MyGUI::xml::ElementPtr code = codes->createChild("Code");
|
||||
code->addAttribute("index", unicodeVal);
|
||||
code->addAttribute("coord", MyGUI::utility::toString(x1) + " "
|
||||
+ MyGUI::utility::toString(y1) + " "
|
||||
+ MyGUI::utility::toString(w) + " "
|
||||
+ MyGUI::utility::toString(h));
|
||||
code->addAttribute("advance", data[i].width);
|
||||
code->addAttribute("bearing", MyGUI::utility::toString(data[i].kerning) + " "
|
||||
+ MyGUI::utility::toString((fontSize-data[i].ascent)));
|
||||
|
||||
// ASCII vertical bar, use this as text input cursor
|
||||
if (i == 124)
|
||||
{
|
||||
MyGUI::xml::ElementPtr cursorCode = codes->createChild("Code");
|
||||
cursorCode->addAttribute("index", MyGUI::FontCodeType::Cursor);
|
||||
cursorCode->addAttribute("coord", MyGUI::utility::toString(x1) + " "
|
||||
+ MyGUI::utility::toString(y1) + " "
|
||||
+ MyGUI::utility::toString(w) + " "
|
||||
+ MyGUI::utility::toString(h));
|
||||
cursorCode->addAttribute("advance", data[i].width);
|
||||
cursorCode->addAttribute("bearing", MyGUI::utility::toString(data[i].kerning) + " "
|
||||
+ MyGUI::utility::toString((fontSize-data[i].ascent)));
|
||||
}
|
||||
}
|
||||
|
||||
// These are required as well, but the fonts don't provide them
|
||||
for (int i=0; i<3; ++i)
|
||||
{
|
||||
MyGUI::FontCodeType::Enum type;
|
||||
if(i == 0)
|
||||
type = MyGUI::FontCodeType::Selected;
|
||||
else if (i == 1)
|
||||
type = MyGUI::FontCodeType::SelectedBack;
|
||||
else if (i == 2)
|
||||
type = MyGUI::FontCodeType::NotDefined;
|
||||
|
||||
MyGUI::xml::ElementPtr cursorCode = codes->createChild("Code");
|
||||
cursorCode->addAttribute("index", type);
|
||||
cursorCode->addAttribute("coord", "0 0 0 0");
|
||||
cursorCode->addAttribute("advance", "0");
|
||||
cursorCode->addAttribute("bearing", "0 0");
|
||||
|
||||
}
|
||||
|
||||
font->deserialization(root, MyGUI::Version(3,2,0));
|
||||
|
||||
MyGUI::ResourceManager::getInstance().addResource(font);
|
||||
}
|
||||
|
||||
}
|
25
apps/openmw/mwgui/fontloader.hpp
Normal file
25
apps/openmw/mwgui/fontloader.hpp
Normal file
@ -0,0 +1,25 @@
|
||||
#ifndef MWGUI_FONTLOADER_H
|
||||
#define MWGUI_FONTLOADER_H
|
||||
|
||||
#include <components/to_utf8/to_utf8.hpp>
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
|
||||
/// @brief loads Morrowind's .fnt/.tex fonts for use with MyGUI and Ogre
|
||||
class FontLoader
|
||||
{
|
||||
public:
|
||||
FontLoader (ToUTF8::FromType encoding);
|
||||
void loadAllFonts ();
|
||||
|
||||
private:
|
||||
ToUTF8::FromType mEncoding;
|
||||
|
||||
void loadFont (const std::string& fileName);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -202,14 +202,14 @@ namespace MWGui
|
||||
|
||||
float BookTextParser::widthForCharGlyph(unsigned unicodeChar) const
|
||||
{
|
||||
std::string fontName(mTextStyle.mFont == "Default" ? "EB Garamond" : mTextStyle.mFont);
|
||||
std::string fontName(mTextStyle.mFont == "Default" ? MyGUI::FontManager::getInstance().getDefaultFont() : mTextStyle.mFont);
|
||||
return MyGUI::FontManager::getInstance().getByName(fontName)
|
||||
->getGlyphInfo(unicodeChar)->width;
|
||||
}
|
||||
|
||||
float BookTextParser::currentFontHeight() const
|
||||
{
|
||||
std::string fontName(mTextStyle.mFont == "Default" ? "EB Garamond" : mTextStyle.mFont);
|
||||
std::string fontName(mTextStyle.mFont == "Default" ? MyGUI::FontManager::getInstance().getDefaultFont() : mTextStyle.mFont);
|
||||
return MyGUI::FontManager::getInstance().getByName(fontName)->getDefaultHeight();
|
||||
}
|
||||
|
||||
@ -251,10 +251,8 @@ namespace MWGui
|
||||
MyGUI::Gui::getInstance().destroyWidget(mParent->getChildAt(0));
|
||||
}
|
||||
|
||||
boost::algorithm::replace_all(text, "\n", "\n");
|
||||
boost::algorithm::replace_all(text, "\r", "\r");
|
||||
boost::algorithm::replace_all(text, "<BR>", "\n\n");
|
||||
boost::algorithm::replace_all(text, "<P>", "\n\n"); // tweaking by adding another newline to see if that spaces out better
|
||||
boost::algorithm::replace_all(text, "<BR>", "\n");
|
||||
boost::algorithm::replace_all(text, "<P>", "\n\n");
|
||||
boost::algorithm::trim_left(text);
|
||||
|
||||
// remove trailing "
|
||||
|
@ -13,8 +13,6 @@ namespace MWGui
|
||||
, mType(Type_Normal)
|
||||
, mBase(base)
|
||||
{
|
||||
assert(base.getContainerStore());
|
||||
|
||||
if (MWWorld::Class::get(base).getEnchantment(base) != "")
|
||||
mFlags |= Flag_Enchanted;
|
||||
}
|
||||
@ -31,18 +29,42 @@ namespace MWGui
|
||||
{
|
||||
if(mBase == other.mBase)
|
||||
return true;
|
||||
return mBase.getContainerStore()->stacks(mBase, other.mBase)
|
||||
&& other.mBase.getContainerStore()->stacks(mBase, other.mBase);
|
||||
|
||||
// If one of the items is in an inventory and currently equipped, we need to check stacking both ways to be sure
|
||||
if (mBase.getContainerStore() && other.mBase.getContainerStore())
|
||||
return mBase.getContainerStore()->stacks(mBase, other.mBase)
|
||||
&& other.mBase.getContainerStore()->stacks(mBase, other.mBase);
|
||||
|
||||
if (mBase.getContainerStore())
|
||||
return mBase.getContainerStore()->stacks(mBase, other.mBase);
|
||||
if (other.mBase.getContainerStore())
|
||||
return other.mBase.getContainerStore()->stacks(mBase, other.mBase);
|
||||
|
||||
MWWorld::ContainerStore store;
|
||||
return store.stacks(mBase, other.mBase);
|
||||
|
||||
}
|
||||
|
||||
bool operator == (const ItemStack& left, const ItemStack& right)
|
||||
{
|
||||
if (left.mType != right.mType)
|
||||
return false;
|
||||
|
||||
if(left.mBase == right.mBase)
|
||||
return true;
|
||||
return left.mBase.getContainerStore()->stacks(left.mBase, right.mBase)
|
||||
&& right.mBase.getContainerStore()->stacks(left.mBase, right.mBase);
|
||||
|
||||
// If one of the items is in an inventory and currently equipped, we need to check stacking both ways to be sure
|
||||
if (left.mBase.getContainerStore() && right.mBase.getContainerStore())
|
||||
return left.mBase.getContainerStore()->stacks(left.mBase, right.mBase)
|
||||
&& right.mBase.getContainerStore()->stacks(left.mBase, right.mBase);
|
||||
|
||||
if (left.mBase.getContainerStore())
|
||||
return left.mBase.getContainerStore()->stacks(left.mBase, right.mBase);
|
||||
if (right.mBase.getContainerStore())
|
||||
return right.mBase.getContainerStore()->stacks(left.mBase, right.mBase);
|
||||
|
||||
MWWorld::ContainerStore store;
|
||||
return store.stacks(left.mBase, right.mBase);
|
||||
}
|
||||
|
||||
ItemModel::ItemModel()
|
||||
|
@ -189,14 +189,14 @@ book JournalBooks::createEmptyJournalBook ()
|
||||
{
|
||||
BookTypesetter::Ptr typesetter = createTypesetter ();
|
||||
|
||||
BookTypesetter::Style* header = typesetter->createStyle ("EB Garamond", MyGUI::Colour (0.60f, 0.00f, 0.00f));
|
||||
BookTypesetter::Style* body = typesetter->createStyle ("EB Garamond", MyGUI::Colour::Black);
|
||||
BookTypesetter::Style* header = typesetter->createStyle ("", MyGUI::Colour (0.60f, 0.00f, 0.00f));
|
||||
BookTypesetter::Style* body = typesetter->createStyle ("", MyGUI::Colour::Black);
|
||||
|
||||
typesetter->write (header, to_utf8_span ("You have no journal entries!"));
|
||||
typesetter->lineBreak ();
|
||||
typesetter->write (body, to_utf8_span ("You should have gone though the starting quest and got an initial quest."));
|
||||
|
||||
BookTypesetter::Style* big = typesetter->createStyle ("EB Garamond 24", MyGUI::Colour::Black);
|
||||
BookTypesetter::Style* big = typesetter->createStyle ("", MyGUI::Colour::Black);
|
||||
BookTypesetter::Style* test = typesetter->createStyle ("MonoFont", MyGUI::Colour::Blue);
|
||||
|
||||
typesetter->sectionBreak (20);
|
||||
@ -231,8 +231,8 @@ book JournalBooks::createJournalBook ()
|
||||
{
|
||||
BookTypesetter::Ptr typesetter = createTypesetter ();
|
||||
|
||||
BookTypesetter::Style* header = typesetter->createStyle ("EB Garamond", MyGUI::Colour (0.60f, 0.00f, 0.00f));
|
||||
BookTypesetter::Style* body = typesetter->createStyle ("EB Garamond", MyGUI::Colour::Black);
|
||||
BookTypesetter::Style* header = typesetter->createStyle ("", MyGUI::Colour (0.60f, 0.00f, 0.00f));
|
||||
BookTypesetter::Style* body = typesetter->createStyle ("", MyGUI::Colour::Black);
|
||||
|
||||
mModel->visitJournalEntries (0, AddJournalEntry (typesetter, body, header, true));
|
||||
|
||||
@ -243,8 +243,8 @@ book JournalBooks::createTopicBook (uintptr_t topicId)
|
||||
{
|
||||
BookTypesetter::Ptr typesetter = createTypesetter ();
|
||||
|
||||
BookTypesetter::Style* header = typesetter->createStyle ("EB Garamond", MyGUI::Colour (0.60f, 0.00f, 0.00f));
|
||||
BookTypesetter::Style* body = typesetter->createStyle ("EB Garamond", MyGUI::Colour::Black);
|
||||
BookTypesetter::Style* header = typesetter->createStyle ("", MyGUI::Colour (0.60f, 0.00f, 0.00f));
|
||||
BookTypesetter::Style* body = typesetter->createStyle ("", MyGUI::Colour::Black);
|
||||
|
||||
mModel->visitTopicName (topicId, AddTopicName (typesetter, header));
|
||||
|
||||
@ -259,8 +259,8 @@ book JournalBooks::createQuestBook (uintptr_t questId)
|
||||
{
|
||||
BookTypesetter::Ptr typesetter = createTypesetter ();
|
||||
|
||||
BookTypesetter::Style* header = typesetter->createStyle ("EB Garamond", MyGUI::Colour (0.60f, 0.00f, 0.00f));
|
||||
BookTypesetter::Style* body = typesetter->createStyle ("EB Garamond", MyGUI::Colour::Black);
|
||||
BookTypesetter::Style* header = typesetter->createStyle ("", MyGUI::Colour (0.60f, 0.00f, 0.00f));
|
||||
BookTypesetter::Style* body = typesetter->createStyle ("", MyGUI::Colour::Black);
|
||||
|
||||
mModel->visitQuestName (questId, AddQuestName (typesetter, header));
|
||||
|
||||
@ -275,7 +275,7 @@ book JournalBooks::createTopicIndexBook ()
|
||||
|
||||
typesetter->setSectionAlignment (BookTypesetter::AlignCenter);
|
||||
|
||||
BookTypesetter::Style* body = typesetter->createStyle ("EB Garamond", MyGUI::Colour::Black);
|
||||
BookTypesetter::Style* body = typesetter->createStyle ("", MyGUI::Colour::Black);
|
||||
|
||||
for (int i = 0; i < 26; ++i)
|
||||
{
|
||||
@ -300,7 +300,7 @@ book JournalBooks::createTopicIndexBook ()
|
||||
book JournalBooks::createTopicIndexBook (char character)
|
||||
{
|
||||
BookTypesetter::Ptr typesetter = BookTypesetter::create (0x7FFFFFFF, 0x7FFFFFFF);
|
||||
BookTypesetter::Style* style = typesetter->createStyle ("EB Garamond", MyGUI::Colour::Black);
|
||||
BookTypesetter::Style* style = typesetter->createStyle ("", MyGUI::Colour::Black);
|
||||
|
||||
mModel->visitTopicNamesStartingWith (character, AddTopicLink (typesetter, style));
|
||||
|
||||
@ -310,7 +310,7 @@ book JournalBooks::createTopicIndexBook (char character)
|
||||
book JournalBooks::createQuestIndexBook (bool activeOnly)
|
||||
{
|
||||
BookTypesetter::Ptr typesetter = BookTypesetter::create (0x7FFFFFFF, 0x7FFFFFFF);
|
||||
BookTypesetter::Style* base = typesetter->createStyle ("EB Garamond", MyGUI::Colour::Black);
|
||||
BookTypesetter::Style* base = typesetter->createStyle ("", MyGUI::Colour::Black);
|
||||
|
||||
mModel->visitQuestNames (activeOnly, AddQuestLink (typesetter, base));
|
||||
|
||||
|
@ -183,7 +183,7 @@ namespace
|
||||
if (!MWBase::Environment::get().getWindowManager ()->getJournalAllowed ())
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->popGuiMode ();
|
||||
}
|
||||
}
|
||||
mModel->load ();
|
||||
|
||||
setBookMode ();
|
||||
@ -433,7 +433,6 @@ namespace
|
||||
void notifyClose(MyGUI::Widget* _sender)
|
||||
{
|
||||
MWBase::Environment::get().getSoundManager()->playSound ("book close", 1.0, 1.0);
|
||||
|
||||
MWBase::Environment::get().getWindowManager ()->popGuiMode ();
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "../mwbase/world.hpp"
|
||||
|
||||
#include "../mwbase/windowmanager.hpp"
|
||||
#include "../mwbase/inputmanager.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
@ -126,7 +127,7 @@ namespace MWGui
|
||||
|
||||
// always update input before rendering something, otherwise mygui goes crazy when something was entered in the frame before
|
||||
// (e.g. when using "coc" console command, it would enter an infinite loop and crash due to overflow)
|
||||
//MWBase::Environment::get().getInputManager()->update(0, true);
|
||||
MWBase::Environment::get().getInputManager()->update(0, true);
|
||||
|
||||
Ogre::CompositorChain* chain = Ogre::CompositorManager::getSingleton().getCompositorChain(mWindow->getViewport(0));
|
||||
|
||||
|
@ -34,6 +34,10 @@ namespace MWGui
|
||||
{
|
||||
}
|
||||
|
||||
LocalMapBase::~LocalMapBase()
|
||||
{
|
||||
}
|
||||
|
||||
void LocalMapBase::init(MyGUI::ScrollView* widget, MyGUI::ImageBox* compass, OEngine::GUI::Layout* layout, bool mapDragAndDrop)
|
||||
{
|
||||
mLocalMap = widget;
|
||||
|
@ -14,6 +14,7 @@ namespace MWGui
|
||||
{
|
||||
public:
|
||||
LocalMapBase();
|
||||
virtual ~LocalMapBase();
|
||||
void init(MyGUI::ScrollView* widget, MyGUI::ImageBox* compass, OEngine::GUI::Layout* layout, bool mapDragAndDrop=false);
|
||||
|
||||
void setCellPrefix(const std::string& prefix);
|
||||
|
@ -32,6 +32,7 @@ namespace MWGui
|
||||
, mFaceIndex(0)
|
||||
, mHairIndex(0)
|
||||
, mCurrentAngle(0)
|
||||
, mPreviewDirty(true)
|
||||
{
|
||||
// Centre dialog
|
||||
center();
|
||||
@ -126,6 +127,8 @@ namespace MWGui
|
||||
mHairIndex = boost::lexical_cast<int>(index) - 1;
|
||||
|
||||
mPreviewImage->setImageTexture ("CharacterHeadPreview");
|
||||
|
||||
mPreviewDirty = true;
|
||||
}
|
||||
|
||||
|
||||
@ -174,6 +177,7 @@ namespace MWGui
|
||||
float angle = (float(_position) / 49.f - 0.5) * 3.14 * 2;
|
||||
float diff = angle - mCurrentAngle;
|
||||
mPreview->update (diff);
|
||||
mPreviewDirty = true;
|
||||
mCurrentAngle += diff;
|
||||
}
|
||||
|
||||
@ -286,6 +290,16 @@ namespace MWGui
|
||||
record.mHair = mAvailableHairs[mHairIndex];
|
||||
|
||||
mPreview->setPrototype(record);
|
||||
mPreviewDirty = true;
|
||||
}
|
||||
|
||||
void RaceDialog::doRenderUpdate()
|
||||
{
|
||||
if (mPreviewDirty)
|
||||
{
|
||||
mPreview->render();
|
||||
mPreviewDirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
void RaceDialog::updateRaces()
|
||||
|
@ -52,6 +52,8 @@ namespace MWGui
|
||||
*/
|
||||
EventHandle_Void eventBack;
|
||||
|
||||
void doRenderUpdate();
|
||||
|
||||
protected:
|
||||
void onHeadRotate(MyGUI::ScrollBar* _sender, size_t _position);
|
||||
|
||||
@ -98,6 +100,8 @@ namespace MWGui
|
||||
float mCurrentAngle;
|
||||
|
||||
MWRender::RaceSelectionPreview* mPreview;
|
||||
|
||||
bool mPreviewDirty;
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user