forked from teamnwah/openmw-tes3coop
Merge remote-tracking branch 'upstream/master' into wizard
This commit is contained in:
commit
ef38fae09d
157 changed files with 3571 additions and 1193 deletions
CMakeLists.txtOFL.txt
apps
opencs
CMakeLists.txteditor.cppeditor.hppmain.cpp
model
tools
world
view
openmw
CMakeLists.txtengine.cppengine.hpp
mwbase
mwclass
mwgui
alchemywindow.cppcontainer.cppdialogue.cpphud.hppinventorywindow.cppitemselection.hppitemview.cppitemview.hppjournalbooks.cppjournalbooks.hpploadingscreen.cppmainmenu.cppmainmenu.hppmode.hppquickkeysmenu.cppsavegamedialog.cppsettingswindow.cppsettingswindow.hppspellwindow.cppspellwindow.hpptradewindow.cpptradewindow.hppvideowidget.cppvideowidget.hppwindowmanagerimp.cppwindowmanagerimp.hpp
mwinput
mwmechanics
|
@ -73,6 +73,8 @@ option(OGRE_STATIC "Link static build of Ogre and Ogre Plugins into the binarie
|
|||
option(BOOST_STATIC "Link static build of Boost into the binaries" FALSE)
|
||||
option(SDL2_STATIC "Link static build of SDL into the binaries" FALSE)
|
||||
|
||||
option(OPENMW_UNITY_BUILD "Use fewer compilation units to speed up compile time" FALSE)
|
||||
|
||||
# Apps and tools
|
||||
option(BUILD_BSATOOL "build BSA extractor" OFF)
|
||||
option(BUILD_ESMTOOL "build ESM inspector" ON)
|
||||
|
@ -131,6 +133,7 @@ set(OENGINE_OGRE
|
|||
|
||||
set(OENGINE_GUI
|
||||
${LIBDIR}/openengine/gui/manager.cpp
|
||||
${LIBDIR}/openengine/gui/layout.hpp
|
||||
)
|
||||
|
||||
set(OENGINE_BULLET
|
||||
|
@ -468,7 +471,6 @@ if(WIN32)
|
|||
INSTALL(FILES
|
||||
"${OpenMW_SOURCE_DIR}/readme.txt"
|
||||
"${OpenMW_SOURCE_DIR}/GPL3.txt"
|
||||
"${OpenMW_SOURCE_DIR}/OFL.txt"
|
||||
"${OpenMW_SOURCE_DIR}/DejaVu Font License.txt"
|
||||
"${OpenMW_BINARY_DIR}/settings-default.cfg"
|
||||
"${OpenMW_BINARY_DIR}/transparency-overrides.cfg"
|
||||
|
|
93
OFL.txt
93
OFL.txt
|
@ -1,93 +0,0 @@
|
|||
Copyright (c) 2010, 2011 Georg Duffner (http://www.georgduffner.at)
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
|
@ -60,20 +60,21 @@ opencs_hdrs_noqt (view/doc
|
|||
opencs_units (view/world
|
||||
table tablesubview scriptsubview util regionmapsubview tablebottombox creator genericcreator
|
||||
cellcreator referenceablecreator referencecreator scenesubview scenetoolbar scenetool
|
||||
scenetoolmode infocreator scriptedit
|
||||
scenetoolmode infocreator scriptedit dialoguesubview previewsubview
|
||||
)
|
||||
|
||||
opencs_units (view/render
|
||||
scenewidget worldspacewidget pagedworldspacewidget unpagedworldspacewidget
|
||||
previewwidget
|
||||
)
|
||||
|
||||
opencs_units_noqt (view/render
|
||||
navigation navigation1st navigationfree navigationorbit
|
||||
navigation navigation1st navigationfree navigationorbit lighting lightingday lightingnight
|
||||
lightingbright
|
||||
)
|
||||
|
||||
opencs_units_noqt (view/world
|
||||
dialoguesubview subviews
|
||||
enumdelegate vartypedelegate recordstatusdelegate idtypedelegate datadisplaydelegate
|
||||
subviews enumdelegate vartypedelegate recordstatusdelegate idtypedelegate datadisplaydelegate
|
||||
scripthighlighter idvalidator dialoguecreator
|
||||
)
|
||||
|
||||
|
@ -147,6 +148,9 @@ if(WIN32)
|
|||
set(QT_USE_QTMAIN TRUE)
|
||||
endif(WIN32)
|
||||
|
||||
set(BOOST_COMPONENTS system filesystem program_options thread wave)
|
||||
find_package(Boost REQUIRED COMPONENTS ${BOOST_COMPONENTS})
|
||||
|
||||
find_package(Qt4 COMPONENTS QtCore QtGui QtNetwork REQUIRED)
|
||||
include(${QT_USE_FILE})
|
||||
|
||||
|
@ -187,6 +191,8 @@ if(APPLE)
|
|||
endif(APPLE)
|
||||
|
||||
target_link_libraries(opencs
|
||||
${OGRE_LIBRARIES}
|
||||
${SHINY_LIBRARIES}
|
||||
${Boost_LIBRARIES}
|
||||
${QT_LIBRARIES}
|
||||
components
|
||||
|
|
|
@ -9,8 +9,13 @@
|
|||
#include <OgreRoot.h>
|
||||
#include <OgreRenderWindow.h>
|
||||
|
||||
#include <extern/shiny/Main/Factory.hpp>
|
||||
#include <extern/shiny/Platforms/Ogre/OgrePlatform.hpp>
|
||||
|
||||
#include <components/ogreinit/ogreinit.hpp>
|
||||
|
||||
#include <components/bsa/resources.hpp>
|
||||
|
||||
#include "model/doc/document.hpp"
|
||||
#include "model/world/data.hpp"
|
||||
|
||||
|
@ -18,14 +23,17 @@ CS::Editor::Editor (OgreInit::OgreInit& ogreInit)
|
|||
: mDocumentManager (mCfgMgr), mViewManager (mDocumentManager),
|
||||
mIpcServerName ("org.openmw.OpenCS")
|
||||
{
|
||||
Files::PathContainer dataDirs = readConfig();
|
||||
std::pair<Files::PathContainer, std::vector<std::string> > config = readConfig();
|
||||
|
||||
setupDataFiles (dataDirs);
|
||||
setupDataFiles (config.first);
|
||||
|
||||
CSMSettings::UserSettings::instance().loadSettings ("opencs.cfg");
|
||||
|
||||
ogreInit.init ((mCfgMgr.getUserConfigPath() / "opencsOgre.log").string());
|
||||
|
||||
Bsa::registerResources (Files::Collections (config.first, !mFsStrict), config.second, true,
|
||||
mFsStrict);
|
||||
|
||||
mNewGame.setLocalData (mLocal);
|
||||
mFileDialog.setLocalData (mLocal);
|
||||
|
||||
|
@ -53,12 +61,12 @@ void CS::Editor::setupDataFiles (const Files::PathContainer& dataDirs)
|
|||
{
|
||||
for (Files::PathContainer::const_iterator iter = dataDirs.begin(); iter != dataDirs.end(); ++iter)
|
||||
{
|
||||
QString path = QString::fromStdString(iter->string());
|
||||
QString path = QString::fromUtf8 (iter->string().c_str());
|
||||
mFileDialog.addFiles(path);
|
||||
}
|
||||
}
|
||||
|
||||
Files::PathContainer CS::Editor::readConfig()
|
||||
std::pair<Files::PathContainer, std::vector<std::string> > CS::Editor::readConfig()
|
||||
{
|
||||
boost::program_options::variables_map variables;
|
||||
boost::program_options::options_description desc("Syntax: opencs <options>\nAllowed options");
|
||||
|
@ -68,13 +76,17 @@ Files::PathContainer CS::Editor::readConfig()
|
|||
("data-local", boost::program_options::value<std::string>()->default_value(""))
|
||||
("fs-strict", boost::program_options::value<bool>()->implicit_value(true)->default_value(false))
|
||||
("encoding", boost::program_options::value<std::string>()->default_value("win1252"))
|
||||
("resources", boost::program_options::value<std::string>()->default_value("resources"));
|
||||
("resources", boost::program_options::value<std::string>()->default_value("resources"))
|
||||
("fallback-archive", boost::program_options::value<std::vector<std::string> >()->
|
||||
default_value(std::vector<std::string>(), "fallback-archive")->multitoken());
|
||||
|
||||
boost::program_options::notify(variables);
|
||||
|
||||
mCfgMgr.readConfiguration(variables, desc);
|
||||
|
||||
mDocumentManager.setResourceDir (variables["resources"].as<std::string>());
|
||||
mDocumentManager.setResourceDir (mResources = variables["resources"].as<std::string>());
|
||||
|
||||
mFsStrict = variables["fs-strict"].as<bool>();
|
||||
|
||||
Files::PathContainer dataDirs, dataLocal;
|
||||
if (!variables["data"].empty()) {
|
||||
|
@ -105,7 +117,7 @@ Files::PathContainer CS::Editor::readConfig()
|
|||
|
||||
dataDirs.insert (dataDirs.end(), dataLocal.begin(), dataLocal.end());
|
||||
|
||||
return dataDirs;
|
||||
return std::make_pair (dataDirs, variables["fallback-archive"].as<std::vector<std::string> >());
|
||||
}
|
||||
|
||||
void CS::Editor::createGame()
|
||||
|
@ -136,7 +148,7 @@ void CS::Editor::openFiles (const boost::filesystem::path &savePath)
|
|||
std::vector<boost::filesystem::path> files;
|
||||
|
||||
foreach (const QString &path, mFileDialog.selectedFilePaths())
|
||||
files.push_back(path.toStdString());
|
||||
files.push_back(path.toUtf8().constData());
|
||||
|
||||
CSMDoc::Document *document = mDocumentManager.addDocument (files, savePath, false);
|
||||
|
||||
|
@ -149,10 +161,10 @@ void CS::Editor::createNewFile (const boost::filesystem::path &savePath)
|
|||
std::vector<boost::filesystem::path> files;
|
||||
|
||||
foreach (const QString &path, mFileDialog.selectedFilePaths()) {
|
||||
files.push_back(path.toStdString());
|
||||
files.push_back(path.toUtf8().constData());
|
||||
}
|
||||
|
||||
files.push_back(mFileDialog.filename().toStdString());
|
||||
files.push_back(mFileDialog.filename().toUtf8().constData());
|
||||
|
||||
CSMDoc::Document *document = mDocumentManager.addDocument (files, savePath, true);
|
||||
|
||||
|
@ -216,6 +228,15 @@ int CS::Editor::run()
|
|||
if (mLocal.empty())
|
||||
return 1;
|
||||
|
||||
mStartup.show();
|
||||
|
||||
QApplication::setQuitOnLastWindowClosed (true);
|
||||
|
||||
return QApplication::exec();
|
||||
}
|
||||
|
||||
std::auto_ptr<sh::Factory> CS::Editor::setupGraphics()
|
||||
{
|
||||
// TODO: setting
|
||||
Ogre::Root::getSingleton().setRenderSystem(Ogre::Root::getSingleton().getRenderSystemByName("OpenGL Rendering Subsystem"));
|
||||
|
||||
|
@ -233,9 +254,36 @@ int CS::Editor::run()
|
|||
Ogre::RenderWindow* hiddenWindow = Ogre::Root::getSingleton().createRenderWindow("InactiveHidden", 1, 1, false, ¶ms);
|
||||
hiddenWindow->setActive(false);
|
||||
|
||||
mStartup.show();
|
||||
sh::OgrePlatform* platform =
|
||||
new sh::OgrePlatform ("General", (mResources / "materials").string());
|
||||
|
||||
QApplication::setQuitOnLastWindowClosed (true);
|
||||
if (!boost::filesystem::exists (mCfgMgr.getCachePath()))
|
||||
boost::filesystem::create_directories (mCfgMgr.getCachePath());
|
||||
|
||||
return QApplication::exec();
|
||||
platform->setCacheFolder (mCfgMgr.getCachePath().string());
|
||||
|
||||
std::auto_ptr<sh::Factory> factory (new sh::Factory (platform));
|
||||
|
||||
factory->setCurrentLanguage (sh::Language_GLSL); /// \todo make this configurable
|
||||
factory->setWriteSourceCache (true);
|
||||
factory->setReadSourceCache (true);
|
||||
factory->setReadMicrocodeCache (true);
|
||||
factory->setWriteMicrocodeCache (true);
|
||||
|
||||
factory->loadAllFiles();
|
||||
|
||||
sh::Factory::getInstance().setGlobalSetting ("fog", "true");
|
||||
|
||||
sh::Factory::getInstance().setGlobalSetting ("shadows", "false");
|
||||
sh::Factory::getInstance().setGlobalSetting ("shadows_pssm", "false");
|
||||
|
||||
sh::Factory::getInstance ().setGlobalSetting ("render_refraction", "false");
|
||||
|
||||
sh::Factory::getInstance ().setGlobalSetting ("viewproj_fix", "false");
|
||||
|
||||
sh::Factory::getInstance ().setGlobalSetting ("num_lights", "8");
|
||||
|
||||
/// \todo add more configurable shiny settings
|
||||
|
||||
return factory;
|
||||
}
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
#ifndef CS_EDITOR_H
|
||||
#define CS_EDITOR_H
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QLocalServer>
|
||||
#include <QLocalSocket>
|
||||
|
||||
#include <extern/shiny/Main/Factory.hpp>
|
||||
|
||||
#ifndef Q_MOC_RUN
|
||||
#include <components/files/configurationmanager.hpp>
|
||||
#endif
|
||||
|
@ -41,12 +45,13 @@ namespace CS
|
|||
CSVDoc::NewGameDialogue mNewGame;
|
||||
CSVSettings::UserSettingsDialog mSettings;
|
||||
CSVDoc::FileDialog mFileDialog;
|
||||
|
||||
boost::filesystem::path mLocal;
|
||||
boost::filesystem::path mResources;
|
||||
bool mFsStrict;
|
||||
|
||||
void setupDataFiles (const Files::PathContainer& dataDirs);
|
||||
|
||||
Files::PathContainer readConfig();
|
||||
std::pair<Files::PathContainer, std::vector<std::string> > readConfig();
|
||||
///< \return data paths
|
||||
|
||||
// not implemented
|
||||
|
@ -63,6 +68,9 @@ namespace CS
|
|||
int run();
|
||||
///< \return error status
|
||||
|
||||
std::auto_ptr<sh::Factory> setupGraphics();
|
||||
///< The returned factory must persist at least as long as *this.
|
||||
|
||||
private slots:
|
||||
|
||||
void createGame();
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#include <QApplication>
|
||||
#include <QIcon>
|
||||
|
||||
#include <extern/shiny/Main/Factory.hpp>
|
||||
|
||||
#include <components/ogreinit/ogreinit.hpp>
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
|
@ -42,6 +44,8 @@ int main(int argc, char *argv[])
|
|||
|
||||
OgreInit::OgreInit ogreInit;
|
||||
|
||||
std::auto_ptr<sh::Factory> shinyFactory;
|
||||
|
||||
Application application (argc, argv);
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
|
@ -73,5 +77,7 @@ int main(int argc, char *argv[])
|
|||
// return 0;
|
||||
}
|
||||
|
||||
shinyFactory = editor.setupGraphics();
|
||||
|
||||
return editor.run();
|
||||
}
|
||||
|
|
|
@ -143,6 +143,6 @@ void CSMTools::Tools::verifierMessage (const QString& message, int type)
|
|||
std::map<int, int>::iterator iter = mActiveReports.find (type);
|
||||
|
||||
if (iter!=mActiveReports.end())
|
||||
mReports[iter->second]->add (message.toStdString());
|
||||
mReports[iter->second]->add (message.toUtf8().constData());
|
||||
}
|
||||
|
||||
|
|
|
@ -448,7 +448,8 @@ namespace CSMWorld
|
|||
template<typename ESXRecordT, typename IdAccessorT>
|
||||
void Collection<ESXRecordT, IdAccessorT>::setRecord (int index, const Record<ESXRecordT>& record)
|
||||
{
|
||||
if (IdAccessorT().getId (mRecords.at (index).get())!=IdAccessorT().getId (record.get()))
|
||||
if (Misc::StringUtils::lowerCase (IdAccessorT().getId (mRecords.at (index).get()))!=
|
||||
Misc::StringUtils::lowerCase (IdAccessorT().getId (record.get())))
|
||||
throw std::runtime_error ("attempt to change the ID of a record");
|
||||
|
||||
mRecords.at (index) = record;
|
||||
|
|
|
@ -17,4 +17,9 @@ bool CSMWorld::ColumnBase::isUserEditable() const
|
|||
std::string CSMWorld::ColumnBase::getTitle() const
|
||||
{
|
||||
return Columns::getName (static_cast<Columns::ColumnId> (mColumnId));
|
||||
}
|
||||
|
||||
int CSMWorld::ColumnBase::getId() const
|
||||
{
|
||||
return mColumnId;
|
||||
}
|
|
@ -28,6 +28,7 @@ namespace CSMWorld
|
|||
{
|
||||
Display_None, //Do not use
|
||||
Display_String,
|
||||
Display_LongString,
|
||||
|
||||
//CONCRETE TYPES STARTS HERE
|
||||
Display_Skill,
|
||||
|
@ -105,6 +106,8 @@ namespace CSMWorld
|
|||
///< Can this column be edited directly by the user?
|
||||
|
||||
virtual std::string getTitle() const;
|
||||
|
||||
virtual int getId() const;
|
||||
};
|
||||
|
||||
template<typename ESXRecordT>
|
||||
|
|
|
@ -37,7 +37,6 @@ namespace CSMWorld
|
|||
}
|
||||
};
|
||||
|
||||
/// \note Shares ID with IdColumn. A table can not have both.
|
||||
template<typename ESXRecordT>
|
||||
struct StringIdColumn : public Column<ESXRecordT>
|
||||
{
|
||||
|
@ -202,7 +201,7 @@ namespace CSMWorld
|
|||
struct DescriptionColumn : public Column<ESXRecordT>
|
||||
{
|
||||
DescriptionColumn()
|
||||
: Column<ESXRecordT> (Columns::ColumnId_Description, ColumnBase::Display_String)
|
||||
: Column<ESXRecordT> (Columns::ColumnId_Description, ColumnBase::Display_LongString)
|
||||
{}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
|
@ -834,15 +833,15 @@ namespace CSMWorld
|
|||
|
||||
virtual bool isUserEditable() const
|
||||
{
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/// \note Shares ID with StringIdColumn. A table can not have both.
|
||||
template<typename ESXRecordT>
|
||||
struct IdColumn : public Column<ESXRecordT>
|
||||
{
|
||||
IdColumn() : Column<ESXRecordT> (Columns::ColumnId_Id, ColumnBase::Display_String) {}
|
||||
IdColumn() : Column<ESXRecordT> (Columns::ColumnId_ReferenceableId,
|
||||
ColumnBase::Display_Referenceable) {}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
|
@ -1114,7 +1113,7 @@ namespace CSMWorld
|
|||
|
||||
virtual bool isUserEditable() const
|
||||
{
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1380,7 +1379,7 @@ namespace CSMWorld
|
|||
template<typename ESXRecordT>
|
||||
struct QuestDescriptionColumn : public Column<ESXRecordT>
|
||||
{
|
||||
QuestDescriptionColumn() : Column<ESXRecordT> (Columns::ColumnId_QuestDescription, ColumnBase::Display_String) {}
|
||||
QuestDescriptionColumn() : Column<ESXRecordT> (Columns::ColumnId_QuestDescription, ColumnBase::Display_LongString) {}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
|
@ -1560,7 +1559,7 @@ namespace CSMWorld
|
|||
template<typename ESXRecordT>
|
||||
struct ResponseColumn : public Column<ESXRecordT>
|
||||
{
|
||||
ResponseColumn() : Column<ESXRecordT> (Columns::ColumnId_Response, ColumnBase::Display_String) {}
|
||||
ResponseColumn() : Column<ESXRecordT> (Columns::ColumnId_Response, ColumnBase::Display_LongString) {}
|
||||
|
||||
virtual QVariant get (const Record<ESXRecordT>& record) const
|
||||
{
|
||||
|
|
|
@ -172,7 +172,8 @@ namespace CSMWorld
|
|||
{ ColumnId_Rank, "Rank" },
|
||||
{ ColumnId_Gender, "Gender" },
|
||||
{ ColumnId_PcRank, "PC Rank" },
|
||||
{ ColumnId_Scope, "Scope", },
|
||||
{ ColumnId_Scope, "Scope" },
|
||||
{ ColumnId_ReferenceableId, "Referenceable ID" },
|
||||
|
||||
{ ColumnId_UseValue1, "Use value 1" },
|
||||
{ ColumnId_UseValue2, "Use value 2" },
|
||||
|
|
|
@ -166,6 +166,7 @@ namespace CSMWorld
|
|||
ColumnId_Gender = 153,
|
||||
ColumnId_PcRank = 154,
|
||||
ColumnId_Scope = 155,
|
||||
ColumnId_ReferenceableId = 156,
|
||||
|
||||
// Allocated to a separate value range, so we don't get a collision should we ever need
|
||||
// to extend the number of use values.
|
||||
|
|
|
@ -250,9 +250,9 @@ CSMWorld::Data::Data() : mRefs (mCells)
|
|||
addModel (new IdTable (&mTopicInfos, IdTable::Reordering_WithinTopic), UniversalId::Type_TopicInfos, UniversalId::Type_TopicInfo);
|
||||
addModel (new IdTable (&mJournalInfos, IdTable::Reordering_WithinTopic), UniversalId::Type_JournalInfos, UniversalId::Type_JournalInfo);
|
||||
addModel (new IdTable (&mCells, IdTable::Reordering_None, IdTable::Viewing_Id), UniversalId::Type_Cells, UniversalId::Type_Cell);
|
||||
addModel (new IdTable (&mReferenceables), UniversalId::Type_Referenceables,
|
||||
UniversalId::Type_Referenceable);
|
||||
addModel (new IdTable (&mRefs, IdTable::Reordering_None, IdTable::Viewing_Cell), UniversalId::Type_References, UniversalId::Type_Reference, false);
|
||||
addModel (new IdTable (&mReferenceables, IdTable::Reordering_None, IdTable::Viewing_None, true),
|
||||
UniversalId::Type_Referenceables, UniversalId::Type_Referenceable);
|
||||
addModel (new IdTable (&mRefs, IdTable::Reordering_None, IdTable::Viewing_Cell, true), UniversalId::Type_References, UniversalId::Type_Reference, false);
|
||||
addModel (new IdTable (&mFilters), UniversalId::Type_Filters, UniversalId::Type_Filter, false);
|
||||
}
|
||||
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
#include "columnbase.hpp"
|
||||
|
||||
CSMWorld::IdTable::IdTable (CollectionBase *idCollection, Reordering reordering,
|
||||
Viewing viewing)
|
||||
: mIdCollection (idCollection), mReordering (reordering), mViewing (viewing)
|
||||
Viewing viewing, bool preview)
|
||||
: mIdCollection (idCollection), mReordering (reordering), mViewing (viewing), mPreview (preview)
|
||||
{}
|
||||
|
||||
CSMWorld::IdTable::~IdTable()
|
||||
|
@ -196,6 +196,11 @@ CSMWorld::IdTable::Viewing CSMWorld::IdTable::getViewing() const
|
|||
return mViewing;
|
||||
}
|
||||
|
||||
bool CSMWorld::IdTable::hasPreview() const
|
||||
{
|
||||
return mPreview;
|
||||
}
|
||||
|
||||
std::pair<CSMWorld::UniversalId, std::string> CSMWorld::IdTable::view (int row) const
|
||||
{
|
||||
std::string id;
|
||||
|
@ -230,4 +235,9 @@ std::pair<CSMWorld::UniversalId, std::string> CSMWorld::IdTable::view (int row)
|
|||
id = "sys::default";
|
||||
|
||||
return std::make_pair (UniversalId (UniversalId::Type_Scene, id), hint);
|
||||
}
|
||||
|
||||
int CSMWorld::IdTable::getColumnId(int column) const
|
||||
{
|
||||
return mIdCollection->getColumn(column).getId();
|
||||
}
|
|
@ -39,6 +39,7 @@ namespace CSMWorld
|
|||
CollectionBase *mIdCollection;
|
||||
Reordering mReordering;
|
||||
Viewing mViewing;
|
||||
bool mPreview;
|
||||
|
||||
// not implemented
|
||||
IdTable (const IdTable&);
|
||||
|
@ -47,7 +48,7 @@ namespace CSMWorld
|
|||
public:
|
||||
|
||||
IdTable (CollectionBase *idCollection, Reordering reordering = Reordering_None,
|
||||
Viewing viewing = Viewing_None);
|
||||
Viewing viewing = Viewing_None, bool preview = false);
|
||||
///< The ownership of \a idCollection is not transferred.
|
||||
|
||||
virtual ~IdTable();
|
||||
|
@ -100,9 +101,13 @@ namespace CSMWorld
|
|||
|
||||
Viewing getViewing() const;
|
||||
|
||||
bool hasPreview() const;
|
||||
|
||||
std::pair<UniversalId, std::string> view (int row) const;
|
||||
///< Return the UniversalId and the hint for viewing \a row. If viewing is not
|
||||
/// supported by this table, return (UniversalId::Type_None, "").
|
||||
|
||||
int getColumnId(int column) const;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ CSMWorld::TableMimeData::TableMimeData (UniversalId id, const CSMDoc::Document&
|
|||
mDocument(document)
|
||||
{
|
||||
mUniversalId.push_back (id);
|
||||
mObjectsFormats << QString::fromStdString ("tabledata/" + id.getTypeName());
|
||||
mObjectsFormats << QString::fromUtf8 (("tabledata/" + id.getTypeName()).c_str());
|
||||
}
|
||||
|
||||
CSMWorld::TableMimeData::TableMimeData (std::vector< CSMWorld::UniversalId >& id, const CSMDoc::Document& document) :
|
||||
|
@ -16,7 +16,7 @@ CSMWorld::TableMimeData::TableMimeData (std::vector< CSMWorld::UniversalId >& id
|
|||
{
|
||||
for (std::vector<UniversalId>::iterator it (mUniversalId.begin()); it != mUniversalId.end(); ++it)
|
||||
{
|
||||
mObjectsFormats << QString::fromStdString ("tabledata/" + it->getTypeName());
|
||||
mObjectsFormats << QString::fromUtf8 (("tabledata/" + it->getTypeName()).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,14 +64,69 @@ std::vector< CSMWorld::UniversalId > CSMWorld::TableMimeData::getData() const
|
|||
return mUniversalId;
|
||||
}
|
||||
|
||||
bool CSMWorld::TableMimeData::isReferencable(CSMWorld::ColumnBase::Display type) const
|
||||
{
|
||||
return ( type == CSMWorld::ColumnBase::Display_Activator
|
||||
|| type == CSMWorld::ColumnBase::Display_Potion
|
||||
|| type == CSMWorld::ColumnBase::Display_Apparatus
|
||||
|| type == CSMWorld::ColumnBase::Display_Armor
|
||||
|| type == CSMWorld::ColumnBase::Display_Book
|
||||
|| type == CSMWorld::ColumnBase::Display_Clothing
|
||||
|| type == CSMWorld::ColumnBase::Display_Container
|
||||
|| type == CSMWorld::ColumnBase::Display_Creature
|
||||
|| type == CSMWorld::ColumnBase::Display_Door
|
||||
|| type == CSMWorld::ColumnBase::Display_Ingredient
|
||||
|| type == CSMWorld::ColumnBase::Display_CreatureLevelledList
|
||||
|| type == CSMWorld::ColumnBase::Display_ItemLevelledList
|
||||
|| type == CSMWorld::ColumnBase::Display_Light
|
||||
|| type == CSMWorld::ColumnBase::Display_Lockpick
|
||||
|| type == CSMWorld::ColumnBase::Display_Miscellaneous
|
||||
|| type == CSMWorld::ColumnBase::Display_Npc
|
||||
|| type == CSMWorld::ColumnBase::Display_Probe
|
||||
|| type == CSMWorld::ColumnBase::Display_Repair
|
||||
|| type == CSMWorld::ColumnBase::Display_Static
|
||||
|| type == CSMWorld::ColumnBase::Display_Weapon);
|
||||
}
|
||||
bool CSMWorld::TableMimeData::isReferencable(CSMWorld::UniversalId::Type type) const
|
||||
{
|
||||
return ( type == CSMWorld::UniversalId::Type_Activator
|
||||
|| type == CSMWorld::UniversalId::Type_Potion
|
||||
|| type == CSMWorld::UniversalId::Type_Apparatus
|
||||
|| type == CSMWorld::UniversalId::Type_Armor
|
||||
|| type == CSMWorld::UniversalId::Type_Book
|
||||
|| type == CSMWorld::UniversalId::Type_Clothing
|
||||
|| type == CSMWorld::UniversalId::Type_Container
|
||||
|| type == CSMWorld::UniversalId::Type_Creature
|
||||
|| type == CSMWorld::UniversalId::Type_Door
|
||||
|| type == CSMWorld::UniversalId::Type_Ingredient
|
||||
|| type == CSMWorld::UniversalId::Type_CreatureLevelledList
|
||||
|| type == CSMWorld::UniversalId::Type_ItemLevelledList
|
||||
|| type == CSMWorld::UniversalId::Type_Light
|
||||
|| type == CSMWorld::UniversalId::Type_Lockpick
|
||||
|| type == CSMWorld::UniversalId::Type_Miscellaneous
|
||||
|| type == CSMWorld::UniversalId::Type_Npc
|
||||
|| type == CSMWorld::UniversalId::Type_Probe
|
||||
|| type == CSMWorld::UniversalId::Type_Repair
|
||||
|| type == CSMWorld::UniversalId::Type_Static
|
||||
|| type == CSMWorld::UniversalId::Type_Weapon);
|
||||
}
|
||||
|
||||
bool CSMWorld::TableMimeData::holdsType (CSMWorld::UniversalId::Type type) const
|
||||
{
|
||||
bool referencable = (type == CSMWorld::UniversalId::Type_Referenceable);
|
||||
for (std::vector<UniversalId>::const_iterator it = mUniversalId.begin(); it != mUniversalId.end(); ++it)
|
||||
{
|
||||
if (it->getType() == type)
|
||||
if (referencable)
|
||||
{
|
||||
return true;
|
||||
if (isReferencable(it->getType()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (it->getType() == type)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -80,11 +135,20 @@ bool CSMWorld::TableMimeData::holdsType (CSMWorld::UniversalId::Type type) const
|
|||
|
||||
bool CSMWorld::TableMimeData::holdsType (CSMWorld::ColumnBase::Display type) const
|
||||
{
|
||||
bool referencable = (type == CSMWorld::ColumnBase::Display_Referenceable);
|
||||
for (std::vector<UniversalId>::const_iterator it = mUniversalId.begin(); it != mUniversalId.end(); ++it)
|
||||
{
|
||||
if (it->getType() == convertEnums (type))
|
||||
if (referencable)
|
||||
{
|
||||
return true;
|
||||
if (isReferencable(it->getType()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (it->getType() == convertEnums (type))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,11 +157,21 @@ bool CSMWorld::TableMimeData::holdsType (CSMWorld::ColumnBase::Display type) con
|
|||
|
||||
CSMWorld::UniversalId CSMWorld::TableMimeData::returnMatching (CSMWorld::UniversalId::Type type) const
|
||||
{
|
||||
bool referencable = (type == CSMWorld::UniversalId::Type_Referenceable);
|
||||
for (std::vector<UniversalId>::const_iterator it = mUniversalId.begin(); it != mUniversalId.end(); ++it)
|
||||
{
|
||||
if (it->getType() == type)
|
||||
if (referencable)
|
||||
{
|
||||
return *it;
|
||||
if (isReferencable(it->getType()))
|
||||
{
|
||||
return *it;
|
||||
}
|
||||
} else
|
||||
{
|
||||
if (it->getType() == type)
|
||||
{
|
||||
return *it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -106,11 +180,20 @@ CSMWorld::UniversalId CSMWorld::TableMimeData::returnMatching (CSMWorld::Univers
|
|||
|
||||
CSMWorld::UniversalId CSMWorld::TableMimeData::returnMatching (CSMWorld::ColumnBase::Display type) const
|
||||
{
|
||||
bool referencable = (type == CSMWorld::ColumnBase::Display_Referenceable);
|
||||
for (std::vector<UniversalId>::const_iterator it = mUniversalId.begin(); it != mUniversalId.end(); ++it)
|
||||
{
|
||||
if (it->getType() == convertEnums (type))
|
||||
if (referencable)
|
||||
{
|
||||
return *it;
|
||||
if (isReferencable(it->getType()))
|
||||
{
|
||||
return *it;
|
||||
}
|
||||
} else {
|
||||
if (it->getType() == convertEnums (type))
|
||||
{
|
||||
return *it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -443,4 +526,9 @@ CSMWorld::ColumnBase::Display CSMWorld::TableMimeData::convertEnums (CSMWorld::U
|
|||
default:
|
||||
return CSMWorld::ColumnBase::Display_None;
|
||||
}
|
||||
}
|
||||
|
||||
const CSMDoc::Document* CSMWorld::TableMimeData::getDocumentPtr() const
|
||||
{
|
||||
return &mDocument;
|
||||
}
|
|
@ -27,6 +27,9 @@ namespace CSMWorld
|
|||
|
||||
class TableMimeData : public QMimeData
|
||||
{
|
||||
std::vector<UniversalId> mUniversalId;
|
||||
QStringList mObjectsFormats;
|
||||
const CSMDoc::Document& mDocument;
|
||||
public:
|
||||
TableMimeData(UniversalId id, const CSMDoc::Document& document);
|
||||
|
||||
|
@ -48,15 +51,16 @@ namespace CSMWorld
|
|||
|
||||
UniversalId returnMatching(UniversalId::Type type) const;
|
||||
|
||||
const CSMDoc::Document* getDocumentPtr() const;
|
||||
|
||||
UniversalId returnMatching(CSMWorld::ColumnBase::Display type) const;
|
||||
|
||||
static CSMWorld::UniversalId::Type convertEnums(CSMWorld::ColumnBase::Display type);
|
||||
static CSMWorld::ColumnBase::Display convertEnums(CSMWorld::UniversalId::Type type);
|
||||
|
||||
private:
|
||||
std::vector<UniversalId> mUniversalId;
|
||||
QStringList mObjectsFormats;
|
||||
const CSMDoc::Document& mDocument;
|
||||
bool isReferencable(CSMWorld::UniversalId::Type type) const;
|
||||
bool isReferencable(CSMWorld::ColumnBase::Display type) const;
|
||||
|
||||
};
|
||||
}
|
||||
|
|
|
@ -92,6 +92,8 @@ namespace
|
|||
{ CSMWorld::UniversalId::Class_SubRecord, CSMWorld::UniversalId::Type_Filter, "Filter", ":./filter.png" },
|
||||
{ CSMWorld::UniversalId::Class_Collection, CSMWorld::UniversalId::Type_Scene, "Scene", 0 },
|
||||
|
||||
{ CSMWorld::UniversalId::Class_Collection, CSMWorld::UniversalId::Type_Preview, "Preview", 0 },
|
||||
|
||||
{ CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0, 0 } // end marker
|
||||
};
|
||||
|
||||
|
|
|
@ -95,7 +95,8 @@ namespace CSMWorld
|
|||
Type_TopicInfo,
|
||||
Type_JournalInfos,
|
||||
Type_JournalInfo,
|
||||
Type_Scene
|
||||
Type_Scene,
|
||||
Type_Preview
|
||||
};
|
||||
|
||||
enum { NumberOfTypes = Type_Scene+1 };
|
||||
|
|
|
@ -40,7 +40,7 @@ OpenDialog::OpenDialog(QWidget * parent) : QDialog(parent)
|
|||
mCfgMgr.processPaths(mDataLocal);
|
||||
|
||||
// Set the charset for reading the esm/esp files
|
||||
QString encoding = QString::fromStdString(variables["encoding"].as<std::string>());
|
||||
QString encoding = QString::fromUtf8 (variables["encoding"].as<std::string>().c_str());
|
||||
|
||||
Files::PathContainer dataDirs;
|
||||
dataDirs.insert(dataDirs.end(), mDataDirs.begin(), mDataDirs.end());
|
||||
|
|
|
@ -4,7 +4,7 @@ CSVDoc::SubView::SubView (const CSMWorld::UniversalId& id) : mUniversalId (id)
|
|||
{
|
||||
/// \todo add a button to the title bar that clones this sub view
|
||||
|
||||
setWindowTitle (mUniversalId.toString().c_str());
|
||||
setWindowTitle (QString::fromUtf8 (mUniversalId.toString().c_str()));
|
||||
}
|
||||
|
||||
CSMWorld::UniversalId CSVDoc::SubView::getUniversalId() const
|
||||
|
@ -18,4 +18,10 @@ void CSVDoc::SubView::updateEditorSetting (const QString &settingName, const QSt
|
|||
|
||||
void CSVDoc::SubView::setStatusBar (bool show) {}
|
||||
|
||||
void CSVDoc::SubView::useHint (const std::string& hint) {}
|
||||
void CSVDoc::SubView::useHint (const std::string& hint) {}
|
||||
|
||||
void CSVDoc::SubView::setUniversalId (const CSMWorld::UniversalId& id)
|
||||
{
|
||||
mUniversalId = id;
|
||||
setWindowTitle (mUniversalId.toString().c_str());
|
||||
}
|
|
@ -27,6 +27,8 @@ namespace CSVDoc
|
|||
// not implemented
|
||||
SubView (const SubView&);
|
||||
SubView& operator= (SubView&);
|
||||
protected:
|
||||
void setUniversalId(const CSMWorld::UniversalId& id);
|
||||
|
||||
public:
|
||||
|
||||
|
|
|
@ -316,8 +316,16 @@ void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id, const std::strin
|
|||
|
||||
/// \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);
|
||||
|
||||
const std::vector<CSMWorld::UniversalId::Type> referenceables(CSMWorld::UniversalId::listReferenceableTypes());
|
||||
SubView *view = NULL;
|
||||
if(std::find(referenceables.begin(), referenceables.end(), id.getType()) != referenceables.end())
|
||||
{
|
||||
view = mSubViewFactory.makeSubView (CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Referenceable, id.getId()), *mDocument);
|
||||
} else
|
||||
{
|
||||
view = mSubViewFactory.makeSubView (id, *mDocument);
|
||||
}
|
||||
assert(view);
|
||||
if (!hint.empty())
|
||||
view->useHint (hint);
|
||||
|
||||
|
|
|
@ -120,7 +120,7 @@ void CSVFilter::EditWidget::createFilterRequest (std::vector< std::pair< std::st
|
|||
{
|
||||
ss<<"!or(";
|
||||
} else {
|
||||
ss << orAnd << oldContent.toStdString() << ',';
|
||||
ss << orAnd << oldContent.toUtf8().constData() << ',';
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < count; ++i)
|
||||
|
@ -137,7 +137,7 @@ void CSVFilter::EditWidget::createFilterRequest (std::vector< std::pair< std::st
|
|||
} else {
|
||||
if (!replaceMode)
|
||||
{
|
||||
ss << orAnd << oldContent.toStdString() <<',';
|
||||
ss << orAnd << oldContent.toUtf8().constData() <<',';
|
||||
} else {
|
||||
ss<<'!';
|
||||
}
|
||||
|
|
4
apps/opencs/view/render/lighting.cpp
Normal file
4
apps/opencs/view/render/lighting.cpp
Normal file
|
@ -0,0 +1,4 @@
|
|||
|
||||
#include "lighting.hpp"
|
||||
|
||||
CSVRender::Lighting::~Lighting() {}
|
27
apps/opencs/view/render/lighting.hpp
Normal file
27
apps/opencs/view/render/lighting.hpp
Normal file
|
@ -0,0 +1,27 @@
|
|||
#ifndef OPENCS_VIEW_LIGHTING_H
|
||||
#define OPENCS_VIEW_LIGHTING_H
|
||||
|
||||
namespace Ogre
|
||||
{
|
||||
class SceneManager;
|
||||
class ColourValue;
|
||||
}
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
class Lighting
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~Lighting();
|
||||
|
||||
virtual void activate (Ogre::SceneManager *sceneManager,
|
||||
const Ogre::ColourValue *defaultAmbient = 0) = 0;
|
||||
|
||||
virtual void deactivate() = 0;
|
||||
|
||||
virtual void setDefaultAmbient (const Ogre::ColourValue& colour) = 0;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
30
apps/opencs/view/render/lightingbright.cpp
Normal file
30
apps/opencs/view/render/lightingbright.cpp
Normal file
|
@ -0,0 +1,30 @@
|
|||
|
||||
#include "lightingbright.hpp"
|
||||
|
||||
#include <OgreSceneManager.h>
|
||||
|
||||
CSVRender::LightingBright::LightingBright() : mSceneManager (0), mLight (0) {}
|
||||
|
||||
void CSVRender::LightingBright::activate (Ogre::SceneManager *sceneManager,
|
||||
const Ogre::ColourValue *defaultAmbient)
|
||||
{
|
||||
mSceneManager = sceneManager;
|
||||
|
||||
mSceneManager->setAmbientLight (Ogre::ColourValue (1.0, 1.0, 1.0, 1));
|
||||
|
||||
mLight = mSceneManager->createLight();
|
||||
mLight->setType (Ogre::Light::LT_DIRECTIONAL);
|
||||
mLight->setDirection (Ogre::Vector3 (0, 0, -1));
|
||||
mLight->setDiffuseColour (Ogre::ColourValue (1.0, 1.0, 1.0));
|
||||
}
|
||||
|
||||
void CSVRender::LightingBright::deactivate()
|
||||
{
|
||||
if (mLight)
|
||||
{
|
||||
mSceneManager->destroyLight (mLight);
|
||||
mLight = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void CSVRender::LightingBright::setDefaultAmbient (const Ogre::ColourValue& colour) {}
|
31
apps/opencs/view/render/lightingbright.hpp
Normal file
31
apps/opencs/view/render/lightingbright.hpp
Normal file
|
@ -0,0 +1,31 @@
|
|||
#ifndef OPENCS_VIEW_LIGHTING_BRIGHT_H
|
||||
#define OPENCS_VIEW_LIGHTING_BRIGHT_H
|
||||
|
||||
#include "lighting.hpp"
|
||||
|
||||
namespace Ogre
|
||||
{
|
||||
class Light;
|
||||
}
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
class LightingBright : public Lighting
|
||||
{
|
||||
Ogre::SceneManager *mSceneManager;
|
||||
Ogre::Light *mLight;
|
||||
|
||||
public:
|
||||
|
||||
LightingBright();
|
||||
|
||||
virtual void activate (Ogre::SceneManager *sceneManager,
|
||||
const Ogre::ColourValue *defaultAmbient = 0);
|
||||
|
||||
virtual void deactivate();
|
||||
|
||||
virtual void setDefaultAmbient (const Ogre::ColourValue& colour);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
36
apps/opencs/view/render/lightingday.cpp
Normal file
36
apps/opencs/view/render/lightingday.cpp
Normal file
|
@ -0,0 +1,36 @@
|
|||
|
||||
#include "lightingday.hpp"
|
||||
|
||||
#include <OgreSceneManager.h>
|
||||
|
||||
CSVRender::LightingDay::LightingDay() : mSceneManager (0), mLight (0) {}
|
||||
|
||||
void CSVRender::LightingDay::activate (Ogre::SceneManager *sceneManager,
|
||||
const Ogre::ColourValue *defaultAmbient)
|
||||
{
|
||||
mSceneManager = sceneManager;
|
||||
|
||||
if (defaultAmbient)
|
||||
mSceneManager->setAmbientLight (*defaultAmbient);
|
||||
else
|
||||
mSceneManager->setAmbientLight (Ogre::ColourValue (0.7, 0.7, 0.7, 1));
|
||||
|
||||
mLight = mSceneManager->createLight();
|
||||
mLight->setType (Ogre::Light::LT_DIRECTIONAL);
|
||||
mLight->setDirection (Ogre::Vector3 (0, 0, -1));
|
||||
mLight->setDiffuseColour (Ogre::ColourValue (1, 1, 1));
|
||||
}
|
||||
|
||||
void CSVRender::LightingDay::deactivate()
|
||||
{
|
||||
if (mLight)
|
||||
{
|
||||
mSceneManager->destroyLight (mLight);
|
||||
mLight = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void CSVRender::LightingDay::setDefaultAmbient (const Ogre::ColourValue& colour)
|
||||
{
|
||||
mSceneManager->setAmbientLight (colour);
|
||||
}
|
31
apps/opencs/view/render/lightingday.hpp
Normal file
31
apps/opencs/view/render/lightingday.hpp
Normal file
|
@ -0,0 +1,31 @@
|
|||
#ifndef OPENCS_VIEW_LIGHTING_DAY_H
|
||||
#define OPENCS_VIEW_LIGHTING_DAY_H
|
||||
|
||||
#include "lighting.hpp"
|
||||
|
||||
namespace Ogre
|
||||
{
|
||||
class Light;
|
||||
}
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
class LightingDay : public Lighting
|
||||
{
|
||||
Ogre::SceneManager *mSceneManager;
|
||||
Ogre::Light *mLight;
|
||||
|
||||
public:
|
||||
|
||||
LightingDay();
|
||||
|
||||
virtual void activate (Ogre::SceneManager *sceneManager,
|
||||
const Ogre::ColourValue *defaultAmbient = 0);
|
||||
|
||||
virtual void deactivate();
|
||||
|
||||
virtual void setDefaultAmbient (const Ogre::ColourValue& colour);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
36
apps/opencs/view/render/lightingnight.cpp
Normal file
36
apps/opencs/view/render/lightingnight.cpp
Normal file
|
@ -0,0 +1,36 @@
|
|||
|
||||
#include "lightingnight.hpp"
|
||||
|
||||
#include <OgreSceneManager.h>
|
||||
|
||||
CSVRender::LightingNight::LightingNight() : mSceneManager (0), mLight (0) {}
|
||||
|
||||
void CSVRender::LightingNight::activate (Ogre::SceneManager *sceneManager,
|
||||
const Ogre::ColourValue *defaultAmbient)
|
||||
{
|
||||
mSceneManager = sceneManager;
|
||||
|
||||
if (defaultAmbient)
|
||||
mSceneManager->setAmbientLight (*defaultAmbient);
|
||||
else
|
||||
mSceneManager->setAmbientLight (Ogre::ColourValue (0.2, 0.2, 0.2, 1));
|
||||
|
||||
mLight = mSceneManager->createLight();
|
||||
mLight->setType (Ogre::Light::LT_DIRECTIONAL);
|
||||
mLight->setDirection (Ogre::Vector3 (0, 0, -1));
|
||||
mLight->setDiffuseColour (Ogre::ColourValue (0.2, 0.2, 0.2));
|
||||
}
|
||||
|
||||
void CSVRender::LightingNight::deactivate()
|
||||
{
|
||||
if (mLight)
|
||||
{
|
||||
mSceneManager->destroyLight (mLight);
|
||||
mLight = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void CSVRender::LightingNight::setDefaultAmbient (const Ogre::ColourValue& colour)
|
||||
{
|
||||
mSceneManager->setAmbientLight (colour);
|
||||
}
|
31
apps/opencs/view/render/lightingnight.hpp
Normal file
31
apps/opencs/view/render/lightingnight.hpp
Normal file
|
@ -0,0 +1,31 @@
|
|||
#ifndef OPENCS_VIEW_LIGHTING_NIGHT_H
|
||||
#define OPENCS_VIEW_LIGHTING_NIGHT_H
|
||||
|
||||
#include "lighting.hpp"
|
||||
|
||||
namespace Ogre
|
||||
{
|
||||
class Light;
|
||||
}
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
class LightingNight : public Lighting
|
||||
{
|
||||
Ogre::SceneManager *mSceneManager;
|
||||
Ogre::Light *mLight;
|
||||
|
||||
public:
|
||||
|
||||
LightingNight();
|
||||
|
||||
virtual void activate (Ogre::SceneManager *sceneManager,
|
||||
const Ogre::ColourValue *defaultAmbient = 0);
|
||||
|
||||
virtual void deactivate();
|
||||
|
||||
virtual void setDefaultAmbient (const Ogre::ColourValue& colour);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -10,7 +10,7 @@ CSVRender::Navigation1st::Navigation1st() : mCamera (0) {}
|
|||
bool CSVRender::Navigation1st::activate (Ogre::Camera *camera)
|
||||
{
|
||||
mCamera = camera;
|
||||
mCamera->setFixedYawAxis (true);
|
||||
mCamera->setFixedYawAxis (true, Ogre::Vector3::UNIT_Z);
|
||||
|
||||
Ogre::Radian pitch = mCamera->getOrientation().getPitch();
|
||||
|
||||
|
|
201
apps/opencs/view/render/previewwidget.cpp
Normal file
201
apps/opencs/view/render/previewwidget.cpp
Normal file
|
@ -0,0 +1,201 @@
|
|||
|
||||
#include "previewwidget.hpp"
|
||||
|
||||
#include <OgreSceneManager.h>
|
||||
#include <OgreSceneNode.h>
|
||||
|
||||
#include "../../model/world/data.hpp"
|
||||
#include "../../model/world/idtable.hpp"
|
||||
|
||||
void CSVRender::PreviewWidget::setup()
|
||||
{
|
||||
setNavigation (&mOrbit);
|
||||
|
||||
mNode = getSceneManager()->getRootSceneNode()->createChildSceneNode();
|
||||
mNode->setPosition (Ogre::Vector3 (0, 0, 0));
|
||||
|
||||
setModel();
|
||||
|
||||
QAbstractItemModel *referenceables =
|
||||
mData.getTableModel (CSMWorld::UniversalId::Type_Referenceables);
|
||||
|
||||
connect (referenceables, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)),
|
||||
this, SLOT (ReferenceableDataChanged (const QModelIndex&, const QModelIndex&)));
|
||||
connect (referenceables, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)),
|
||||
this, SLOT (ReferenceableAboutToBeRemoved (const QModelIndex&, int, int)));
|
||||
}
|
||||
|
||||
void CSVRender::PreviewWidget::setModel()
|
||||
{
|
||||
if (mNode)
|
||||
{
|
||||
mObject.setNull();
|
||||
|
||||
if (mReferenceableId.empty())
|
||||
return;
|
||||
|
||||
int column =
|
||||
mData.getReferenceables().findColumnIndex (CSMWorld::Columns::ColumnId_Model);
|
||||
|
||||
int row = mData.getReferenceables().searchId (mReferenceableId);
|
||||
|
||||
if (row==-1)
|
||||
return;
|
||||
|
||||
QVariant value = mData.getReferenceables().getData (row, column);
|
||||
|
||||
if (!value.isValid())
|
||||
return;
|
||||
|
||||
std::string model = value.toString().toUtf8().constData();
|
||||
|
||||
if (model.empty())
|
||||
return;
|
||||
|
||||
mObject = NifOgre::Loader::createObjects (mNode, "Meshes\\" + model);
|
||||
}
|
||||
}
|
||||
|
||||
void CSVRender::PreviewWidget::adjust()
|
||||
{
|
||||
if (mNode)
|
||||
{
|
||||
int row = mData.getReferences().getIndex (mReferenceId);
|
||||
|
||||
float scale = mData.getReferences().getData (row, mData.getReferences().
|
||||
findColumnIndex (CSMWorld::Columns::ColumnId_Scale)).toFloat();
|
||||
float rotX = mData.getReferences().getData (row, mData.getReferences().
|
||||
findColumnIndex (CSMWorld::Columns::ColumnId_PositionXRot)).toFloat();
|
||||
float rotY = mData.getReferences().getData (row, mData.getReferences().
|
||||
findColumnIndex (CSMWorld::Columns::ColumnId_PositionYRot)).toFloat();
|
||||
float rotZ = mData.getReferences().getData (row, mData.getReferences().
|
||||
findColumnIndex (CSMWorld::Columns::ColumnId_PositionZRot)).toFloat();
|
||||
|
||||
mNode->setScale (scale, scale, scale);
|
||||
|
||||
Ogre::Quaternion xr (Ogre::Radian(-rotX), Ogre::Vector3::UNIT_X);
|
||||
|
||||
Ogre::Quaternion yr (Ogre::Radian(-rotY), Ogre::Vector3::UNIT_Y);
|
||||
|
||||
Ogre::Quaternion zr (Ogre::Radian(-rotZ), Ogre::Vector3::UNIT_Z);
|
||||
|
||||
mNode->setOrientation (xr*yr*zr);
|
||||
}
|
||||
}
|
||||
|
||||
CSVRender::PreviewWidget::PreviewWidget (CSMWorld::Data& data,
|
||||
const std::string& referenceableId, QWidget *parent)
|
||||
: SceneWidget (parent), mData (data), mNode (0), mReferenceableId (referenceableId)
|
||||
{
|
||||
setup();
|
||||
}
|
||||
|
||||
CSVRender::PreviewWidget::PreviewWidget (CSMWorld::Data& data,
|
||||
const std::string& referenceableId, const std::string& referenceId, QWidget *parent)
|
||||
: SceneWidget (parent), mData (data), mReferenceableId (referenceableId),
|
||||
mReferenceId (referenceId)
|
||||
{
|
||||
setup();
|
||||
|
||||
adjust();
|
||||
|
||||
QAbstractItemModel *references =
|
||||
mData.getTableModel (CSMWorld::UniversalId::Type_References);
|
||||
|
||||
connect (references, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)),
|
||||
this, SLOT (ReferenceDataChanged (const QModelIndex&, const QModelIndex&)));
|
||||
connect (references, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)),
|
||||
this, SLOT (ReferenceAboutToBeRemoved (const QModelIndex&, int, int)));
|
||||
}
|
||||
|
||||
void CSVRender::PreviewWidget::ReferenceableDataChanged (const QModelIndex& topLeft,
|
||||
const QModelIndex& bottomRight)
|
||||
{
|
||||
if (mReferenceableId.empty())
|
||||
return;
|
||||
|
||||
CSMWorld::IdTable& referenceables = dynamic_cast<CSMWorld::IdTable&> (
|
||||
*mData.getTableModel (CSMWorld::UniversalId::Type_Referenceables));
|
||||
|
||||
QModelIndex index = referenceables.getModelIndex (mReferenceableId, 0);
|
||||
|
||||
if (index.row()>=topLeft.row() && index.row()<=bottomRight.row())
|
||||
{
|
||||
/// \todo possible optimisation; check columns and only update if relevant columns have
|
||||
/// changed
|
||||
setModel();
|
||||
flagAsModified();
|
||||
}
|
||||
}
|
||||
|
||||
void CSVRender::PreviewWidget::ReferenceableAboutToBeRemoved (const QModelIndex& parent, int start,
|
||||
int end)
|
||||
{
|
||||
if (mReferenceableId.empty())
|
||||
return;
|
||||
|
||||
CSMWorld::IdTable& referenceables = dynamic_cast<CSMWorld::IdTable&> (
|
||||
*mData.getTableModel (CSMWorld::UniversalId::Type_Referenceables));
|
||||
|
||||
QModelIndex index = referenceables.getModelIndex (mReferenceableId, 0);
|
||||
|
||||
if (index.row()>=start && index.row()<=end)
|
||||
{
|
||||
if (mReferenceId.empty())
|
||||
{
|
||||
// this is a preview for a referenceble
|
||||
emit closeRequest();
|
||||
}
|
||||
else
|
||||
{
|
||||
// this is a preview for a reference
|
||||
mObject.setNull();
|
||||
flagAsModified();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSVRender::PreviewWidget::ReferenceDataChanged (const QModelIndex& topLeft,
|
||||
const QModelIndex& bottomRight)
|
||||
{
|
||||
if (mReferenceId.empty())
|
||||
return;
|
||||
|
||||
CSMWorld::IdTable& references = dynamic_cast<CSMWorld::IdTable&> (
|
||||
*mData.getTableModel (CSMWorld::UniversalId::Type_References));
|
||||
|
||||
int columnIndex = references.findColumnIndex (CSMWorld::Columns::ColumnId_ReferenceableId);
|
||||
|
||||
QModelIndex index = references.getModelIndex (mReferenceId, columnIndex);
|
||||
|
||||
if (index.row()>=topLeft.row() && index.row()<=bottomRight.row())
|
||||
{
|
||||
/// \todo possible optimisation; check columns and only update if relevant columns have
|
||||
/// changed
|
||||
adjust();
|
||||
|
||||
if (index.column()>=topLeft.column() && index.column()<=bottomRight.row())
|
||||
{
|
||||
mReferenceableId = references.data (index).toString().toUtf8().constData();
|
||||
emit referenceableIdChanged (mReferenceableId);
|
||||
setModel();
|
||||
}
|
||||
|
||||
flagAsModified();
|
||||
}
|
||||
}
|
||||
|
||||
void CSVRender::PreviewWidget::ReferenceAboutToBeRemoved (const QModelIndex& parent, int start,
|
||||
int end)
|
||||
{
|
||||
if (mReferenceId.empty())
|
||||
return;
|
||||
|
||||
CSMWorld::IdTable& references = dynamic_cast<CSMWorld::IdTable&> (
|
||||
*mData.getTableModel (CSMWorld::UniversalId::Type_References));
|
||||
|
||||
QModelIndex index = references.getModelIndex (mReferenceId, 0);
|
||||
|
||||
if (index.row()>=start && index.row()<=end)
|
||||
emit closeRequest();
|
||||
}
|
64
apps/opencs/view/render/previewwidget.hpp
Normal file
64
apps/opencs/view/render/previewwidget.hpp
Normal file
|
@ -0,0 +1,64 @@
|
|||
#ifndef OPENCS_VIEW_PREVIEWWIDGET_H
|
||||
#define OPENCS_VIEW_PREVIEWWIDGET_H
|
||||
|
||||
#include <components/nifogre/ogrenifloader.hpp>
|
||||
|
||||
#include "scenewidget.hpp"
|
||||
|
||||
#include "navigationorbit.hpp"
|
||||
|
||||
class QModelIndex;
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class Data;
|
||||
}
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
class PreviewWidget : public SceneWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
CSMWorld::Data& mData;
|
||||
CSVRender::NavigationOrbit mOrbit;
|
||||
NifOgre::ObjectScenePtr mObject;
|
||||
Ogre::SceneNode *mNode;
|
||||
std::string mReferenceId;
|
||||
std::string mReferenceableId;
|
||||
|
||||
void setup();
|
||||
|
||||
void setModel();
|
||||
|
||||
void adjust();
|
||||
///< Adjust referenceable preview according to the reference
|
||||
|
||||
public:
|
||||
|
||||
PreviewWidget (CSMWorld::Data& data, const std::string& referenceableId,
|
||||
QWidget *parent = 0);
|
||||
|
||||
PreviewWidget (CSMWorld::Data& data, const std::string& referenceableId,
|
||||
const std::string& referenceId, QWidget *parent = 0);
|
||||
|
||||
signals:
|
||||
|
||||
void closeRequest();
|
||||
|
||||
void referenceableIdChanged (const std::string& id);
|
||||
|
||||
private slots:
|
||||
|
||||
void ReferenceableDataChanged (const QModelIndex& topLeft,
|
||||
const QModelIndex& bottomRight);
|
||||
|
||||
void ReferenceableAboutToBeRemoved (const QModelIndex& parent, int start, int end);
|
||||
|
||||
void ReferenceDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight);
|
||||
|
||||
void ReferenceAboutToBeRemoved (const QModelIndex& parent, int start, int end);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -11,7 +11,10 @@
|
|||
#include <OgreSceneNode.h>
|
||||
#include <OgreViewport.h>
|
||||
|
||||
#include "../world/scenetoolmode.hpp"
|
||||
|
||||
#include "navigation.hpp"
|
||||
#include "lighting.hpp"
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
|
@ -19,11 +22,12 @@ namespace CSVRender
|
|||
: QWidget(parent)
|
||||
, mWindow(NULL)
|
||||
, mCamera(NULL)
|
||||
, mSceneMgr(NULL), mNavigation (0), mUpdate (false)
|
||||
, mSceneMgr(NULL), mNavigation (0), mLighting (0), mUpdate (false)
|
||||
, mKeyForward (false), mKeyBackward (false), mKeyLeft (false), mKeyRight (false)
|
||||
, mKeyRollLeft (false), mKeyRollRight (false)
|
||||
, mFast (false), mDragging (false), mMod1 (false)
|
||||
, mFastFactor (4) /// \todo make this configurable
|
||||
, mDefaultAmbient (0, 0, 0, 0), mHasDefaultAmbient (false)
|
||||
{
|
||||
setAttribute(Qt::WA_PaintOnScreen);
|
||||
setAttribute(Qt::WA_NoSystemBackground);
|
||||
|
@ -32,28 +36,17 @@ namespace CSVRender
|
|||
|
||||
mSceneMgr = Ogre::Root::getSingleton().createSceneManager(Ogre::ST_GENERIC);
|
||||
|
||||
// Throw in a random color just to make sure multiple scenes work
|
||||
Ogre::Real r = Ogre::Math::RangeRandom(0, 1);
|
||||
Ogre::Real g = Ogre::Math::RangeRandom(0, 1);
|
||||
Ogre::Real b = Ogre::Math::RangeRandom(0, 1);
|
||||
mSceneMgr->setAmbientLight(Ogre::ColourValue(r,g,b,1));
|
||||
|
||||
Ogre::Light* l = mSceneMgr->createLight();
|
||||
l->setType (Ogre::Light::LT_DIRECTIONAL);
|
||||
l->setDirection (Ogre::Vector3(-0.4, -0.7, 0.3));
|
||||
l->setDiffuseColour (Ogre::ColourValue(0.7,0.7,0.7));
|
||||
mSceneMgr->setAmbientLight (Ogre::ColourValue (0,0,0,1));
|
||||
|
||||
mCamera = mSceneMgr->createCamera("foo");
|
||||
|
||||
Ogre::Entity* ent = mSceneMgr->createEntity("cube", Ogre::SceneManager::PT_CUBE);
|
||||
ent->setMaterialName("BaseWhite");
|
||||
mCamera->setPosition (300, 0, 0);
|
||||
mCamera->lookAt (0, 0, 0);
|
||||
mCamera->setNearClipDistance (0.1);
|
||||
mCamera->setFarClipDistance (30000);
|
||||
mCamera->roll (Ogre::Degree (90));
|
||||
|
||||
mSceneMgr->getRootSceneNode()->attachObject(ent);
|
||||
|
||||
mCamera->setPosition(300,300,300);
|
||||
mCamera->lookAt(0,0,0);
|
||||
mCamera->setNearClipDistance(0.1);
|
||||
mCamera->setFarClipDistance(3000);
|
||||
setLighting (&mLightingDay);
|
||||
|
||||
QTimer *timer = new QTimer (this);
|
||||
|
||||
|
@ -61,9 +54,27 @@ namespace CSVRender
|
|||
timer->start (20); /// \todo make this configurable
|
||||
}
|
||||
|
||||
void SceneWidget::setAmbient (const Ogre::ColourValue& colour)
|
||||
CSVWorld::SceneToolMode *SceneWidget::makeLightingSelector (CSVWorld::SceneToolbar *parent)
|
||||
{
|
||||
mSceneMgr->setAmbientLight (colour);
|
||||
CSVWorld::SceneToolMode *tool = new CSVWorld::SceneToolMode (parent);
|
||||
|
||||
tool->addButton (":door.png", "day"); /// \todo replace icons
|
||||
tool->addButton (":GMST.png", "night");
|
||||
tool->addButton (":Info.png", "bright");
|
||||
|
||||
connect (tool, SIGNAL (modeChanged (const std::string&)),
|
||||
this, SLOT (selectLightingMode (const std::string&)));
|
||||
|
||||
return tool;
|
||||
}
|
||||
|
||||
void SceneWidget::setDefaultAmbient (const Ogre::ColourValue& colour)
|
||||
{
|
||||
mDefaultAmbient = colour;
|
||||
mHasDefaultAmbient = true;
|
||||
|
||||
if (mLighting)
|
||||
mLighting->setDefaultAmbient (colour);
|
||||
}
|
||||
|
||||
void SceneWidget::updateOgreWindow()
|
||||
|
@ -118,6 +129,16 @@ namespace CSVRender
|
|||
}
|
||||
}
|
||||
|
||||
Ogre::SceneManager *SceneWidget::getSceneManager()
|
||||
{
|
||||
return mSceneMgr;
|
||||
}
|
||||
|
||||
void SceneWidget::flagAsModified()
|
||||
{
|
||||
mUpdate = true;
|
||||
}
|
||||
|
||||
void SceneWidget::paintEvent(QPaintEvent* e)
|
||||
{
|
||||
if (!mWindow)
|
||||
|
@ -310,4 +331,23 @@ namespace CSVRender
|
|||
{
|
||||
return mFast ? mFastFactor : 1;
|
||||
}
|
||||
|
||||
void SceneWidget::setLighting (Lighting *lighting)
|
||||
{
|
||||
if (mLighting)
|
||||
mLighting->deactivate();
|
||||
|
||||
mLighting = lighting;
|
||||
mLighting->activate (mSceneMgr, mHasDefaultAmbient ? &mDefaultAmbient : 0);
|
||||
}
|
||||
|
||||
void SceneWidget::selectLightingMode (const std::string& mode)
|
||||
{
|
||||
if (mode=="day")
|
||||
setLighting (&mLightingDay);
|
||||
else if (mode=="night")
|
||||
setLighting (&mLightingNight);
|
||||
else if (mode=="bright")
|
||||
setLighting (&mLightingBright);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,17 +3,29 @@
|
|||
|
||||
#include <QWidget>
|
||||
|
||||
#include <OgreColourValue.h>
|
||||
|
||||
#include "lightingday.hpp"
|
||||
#include "lightingnight.hpp"
|
||||
#include "lightingbright.hpp"
|
||||
|
||||
namespace Ogre
|
||||
{
|
||||
class Camera;
|
||||
class SceneManager;
|
||||
class RenderWindow;
|
||||
class ColourValue;
|
||||
}
|
||||
|
||||
namespace CSVWorld
|
||||
{
|
||||
class SceneToolMode;
|
||||
class SceneToolbar;
|
||||
}
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
class Navigation;
|
||||
class Lighting;
|
||||
|
||||
class SceneWidget : public QWidget
|
||||
{
|
||||
|
@ -26,14 +38,22 @@ namespace CSVRender
|
|||
|
||||
QPaintEngine* paintEngine() const;
|
||||
|
||||
void setAmbient (const Ogre::ColourValue& colour);
|
||||
///< \note The actual ambient colour may differ based on lighting settings.
|
||||
CSVWorld::SceneToolMode *makeLightingSelector (CSVWorld::SceneToolbar *parent);
|
||||
///< \attention The created tool is not added to the toolbar (via addTool). Doing that
|
||||
/// is the responsibility of the calling function.
|
||||
|
||||
protected:
|
||||
|
||||
void setNavigation (Navigation *navigation);
|
||||
///< \attention The ownership of \a navigation is not transferred to *this.
|
||||
|
||||
Ogre::SceneManager *getSceneManager();
|
||||
|
||||
void flagAsModified();
|
||||
|
||||
void setDefaultAmbient (const Ogre::ColourValue& colour);
|
||||
///< \note The actual ambient colour may differ based on lighting settings.
|
||||
|
||||
private:
|
||||
void paintEvent(QPaintEvent* e);
|
||||
void resizeEvent(QResizeEvent* e);
|
||||
|
@ -57,11 +77,15 @@ namespace CSVRender
|
|||
|
||||
int getFastFactor() const;
|
||||
|
||||
void setLighting (Lighting *lighting);
|
||||
///< \attention The ownership of \a lighting is not transferred to *this.
|
||||
|
||||
Ogre::Camera* mCamera;
|
||||
Ogre::SceneManager* mSceneMgr;
|
||||
Ogre::RenderWindow* mWindow;
|
||||
|
||||
Navigation *mNavigation;
|
||||
Lighting *mLighting;
|
||||
bool mUpdate;
|
||||
bool mKeyForward;
|
||||
bool mKeyBackward;
|
||||
|
@ -74,10 +98,17 @@ namespace CSVRender
|
|||
bool mMod1;
|
||||
QPoint mOldPos;
|
||||
int mFastFactor;
|
||||
Ogre::ColourValue mDefaultAmbient;
|
||||
bool mHasDefaultAmbient;
|
||||
LightingDay mLightingDay;
|
||||
LightingNight mLightingNight;
|
||||
LightingBright mLightingBright;
|
||||
|
||||
private slots:
|
||||
|
||||
void update();
|
||||
|
||||
void selectLightingMode (const std::string& mode);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ void CSVRender::UnpagedWorldspaceWidget::update()
|
|||
|
||||
Ogre::ColourValue colour;
|
||||
colour.setAsABGR (record.get().mAmbi.mAmbient);
|
||||
setAmbient (colour);
|
||||
setDefaultAmbient (colour);
|
||||
|
||||
/// \todo deal with mSunlight and mFog/mForDensity
|
||||
}
|
||||
|
|
|
@ -1,11 +1,20 @@
|
|||
|
||||
#include "worldspacewidget.hpp"
|
||||
|
||||
#include <OgreSceneNode.h>
|
||||
#include <OgreSceneManager.h>
|
||||
#include <OgreEntity.h>
|
||||
|
||||
#include "../world/scenetoolmode.hpp"
|
||||
|
||||
CSVRender::WorldspaceWidget::WorldspaceWidget (QWidget *parent)
|
||||
: SceneWidget (parent)
|
||||
{}
|
||||
{
|
||||
Ogre::Entity* ent = getSceneManager()->createEntity("cube", Ogre::SceneManager::PT_CUBE);
|
||||
ent->setMaterialName("BaseWhite");
|
||||
|
||||
getSceneManager()->getRootSceneNode()->attachObject(ent);
|
||||
}
|
||||
|
||||
void CSVRender::WorldspaceWidget::selectNavigationMode (const std::string& mode)
|
||||
{
|
||||
|
|
|
@ -28,7 +28,7 @@ namespace CSVRender
|
|||
WorldspaceWidget (QWidget *parent = 0);
|
||||
|
||||
CSVWorld::SceneToolMode *makeNavigationSelector (CSVWorld::SceneToolbar *parent);
|
||||
///< \important The created tool is not added to the toolbar (via addTool). Doing that
|
||||
///< \attention The created tool is not added to the toolbar (via addTool). Doing that
|
||||
/// is the responsibility of the calling function.
|
||||
|
||||
void selectDefaultNavigationMode();
|
||||
|
|
|
@ -1,98 +1,689 @@
|
|||
|
||||
#include "dialoguesubview.hpp"
|
||||
|
||||
#include <utility>
|
||||
#include <memory>
|
||||
|
||||
#include <QGridLayout>
|
||||
#include <QLabel>
|
||||
#include <QSize>
|
||||
#include <QAbstractItemModel>
|
||||
#include <QDoubleSpinBox>
|
||||
#include <QSpinBox>
|
||||
#include <QLineEdit>
|
||||
#include <QEvent>
|
||||
#include <QDataWidgetMapper>
|
||||
#include <QCheckBox>
|
||||
#include <QLineEdit>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QComboBox>
|
||||
#include <QScrollArea>
|
||||
#include <QPushButton>
|
||||
#include <QToolButton>
|
||||
|
||||
#include "../../model/world/columnbase.hpp"
|
||||
#include "../../model/world/idtable.hpp"
|
||||
#include "../../model/world/columns.hpp"
|
||||
#include "../../model/world/record.hpp"
|
||||
#include "../../model/world/tablemimedata.hpp"
|
||||
#include "../../model/doc/document.hpp"
|
||||
#include "../../model/world/commands.hpp"
|
||||
|
||||
CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document,
|
||||
bool createAndDelete)
|
||||
: SubView (id)
|
||||
#include "recordstatusdelegate.hpp"
|
||||
#include "util.hpp"
|
||||
#include "tablebottombox.hpp"
|
||||
/*
|
||||
==============================NotEditableSubDelegate==========================================
|
||||
*/
|
||||
CSVWorld::NotEditableSubDelegate::NotEditableSubDelegate(const CSMWorld::IdTable* table, QObject * parent) :
|
||||
QAbstractItemDelegate(parent),
|
||||
mTable(table)
|
||||
{}
|
||||
|
||||
void CSVWorld::NotEditableSubDelegate::setEditorData (QLabel* editor, const QModelIndex& index) const
|
||||
{
|
||||
QWidget *widget = new QWidget (this);
|
||||
|
||||
setWidget (widget);
|
||||
|
||||
QGridLayout *layout = new QGridLayout;
|
||||
|
||||
widget->setLayout (layout);
|
||||
|
||||
QAbstractItemModel *model = document.getData().getTableModel (id);
|
||||
|
||||
int columns = model->columnCount();
|
||||
|
||||
mWidgetMapper = new QDataWidgetMapper (this);
|
||||
mWidgetMapper->setModel (model);
|
||||
|
||||
for (int i=0; i<columns; ++i)
|
||||
QVariant v = index.data(Qt::EditRole);
|
||||
if (!v.isValid())
|
||||
{
|
||||
int flags = model->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Flags).toInt();
|
||||
|
||||
if (flags & CSMWorld::ColumnBase::Flag_Dialogue)
|
||||
v = index.data(Qt::DisplayRole);
|
||||
if (!v.isValid())
|
||||
{
|
||||
layout->addWidget (new QLabel (model->headerData (i, Qt::Horizontal).toString()), i, 0);
|
||||
|
||||
CSMWorld::ColumnBase::Display display = static_cast<CSMWorld::ColumnBase::Display>
|
||||
(model->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt());
|
||||
|
||||
QWidget *widget = 0;
|
||||
|
||||
if (model->flags (model->index (0, i)) & Qt::ItemIsEditable)
|
||||
{
|
||||
switch (display)
|
||||
{
|
||||
case CSMWorld::ColumnBase::Display_String:
|
||||
|
||||
layout->addWidget (widget = new QLineEdit, i, 1);
|
||||
break;
|
||||
|
||||
case CSMWorld::ColumnBase::Display_Integer:
|
||||
|
||||
/// \todo configure widget properly (range)
|
||||
layout->addWidget (widget = new QSpinBox, i, 1);
|
||||
break;
|
||||
|
||||
case CSMWorld::ColumnBase::Display_Float:
|
||||
|
||||
/// \todo configure widget properly (range, format?)
|
||||
layout->addWidget (widget = new QDoubleSpinBox, i, 1);
|
||||
break;
|
||||
|
||||
default: break; // silence warnings for other times for now
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (display)
|
||||
{
|
||||
case CSMWorld::ColumnBase::Display_String:
|
||||
case CSMWorld::ColumnBase::Display_Integer:
|
||||
case CSMWorld::ColumnBase::Display_Float:
|
||||
|
||||
layout->addWidget (widget = new QLabel, i, 1);
|
||||
break;
|
||||
|
||||
default: break; // silence warnings for other times for now
|
||||
}
|
||||
}
|
||||
|
||||
if (widget)
|
||||
mWidgetMapper->addMapping (widget, i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
mWidgetMapper->setCurrentModelIndex (
|
||||
dynamic_cast<CSMWorld::IdTable&> (*model).getModelIndex (id.getId(), 0));
|
||||
if (QVariant::String == v.type())
|
||||
{
|
||||
editor->setText(v.toString());
|
||||
} else //else we are facing enums
|
||||
{
|
||||
int data = v.toInt();
|
||||
std::vector<std::string> enumNames (CSMWorld::Columns::getEnums (static_cast<CSMWorld::Columns::ColumnId> (mTable->getColumnId (index.column()))));
|
||||
editor->setText(QString::fromUtf8(enumNames.at(data).c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
void CSVWorld::NotEditableSubDelegate::setModelData (QWidget* editor, QAbstractItemModel* model, const QModelIndex& index, CSMWorld::ColumnBase::Display display) const
|
||||
{
|
||||
//not editable widgets will not save model data
|
||||
}
|
||||
|
||||
void CSVWorld::NotEditableSubDelegate::paint (QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||
{
|
||||
//does nothing
|
||||
}
|
||||
|
||||
QSize CSVWorld::NotEditableSubDelegate::sizeHint (const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||
{
|
||||
return QSize();
|
||||
}
|
||||
|
||||
QWidget* CSVWorld::NotEditableSubDelegate::createEditor (QWidget *parent,
|
||||
const QStyleOptionViewItem& option,
|
||||
const QModelIndex& index,
|
||||
CSMWorld::ColumnBase::Display display) const
|
||||
{
|
||||
return new QLabel(parent);
|
||||
}
|
||||
|
||||
/*
|
||||
==============================DialogueDelegateDispatcherProxy==========================================
|
||||
*/
|
||||
CSVWorld::DialogueDelegateDispatcherProxy::refWrapper::refWrapper(const QModelIndex& index) :
|
||||
mIndex(index)
|
||||
{}
|
||||
|
||||
CSVWorld::DialogueDelegateDispatcherProxy::DialogueDelegateDispatcherProxy(QWidget* editor, CSMWorld::ColumnBase::Display display) :
|
||||
mEditor(editor),
|
||||
mDisplay(display),
|
||||
mIndexWrapper(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
void CSVWorld::DialogueDelegateDispatcherProxy::editorDataCommited()
|
||||
{
|
||||
if (mIndexWrapper.get())
|
||||
{
|
||||
emit editorDataCommited(mEditor, mIndexWrapper->mIndex, mDisplay);
|
||||
}
|
||||
}
|
||||
|
||||
void CSVWorld::DialogueDelegateDispatcherProxy::setIndex(const QModelIndex& index)
|
||||
{
|
||||
mIndexWrapper.reset(new refWrapper(index));
|
||||
}
|
||||
|
||||
QWidget* CSVWorld::DialogueDelegateDispatcherProxy::getEditor() const
|
||||
{
|
||||
return mEditor;
|
||||
}
|
||||
|
||||
void CSVWorld::DialogueDelegateDispatcherProxy::tableMimeDataDropped(const std::vector<CSMWorld::UniversalId>& data, const CSMDoc::Document* document)
|
||||
{
|
||||
QLineEdit* lineEdit = qobject_cast<QLineEdit*>(mEditor);
|
||||
{
|
||||
if (!lineEdit || !mIndexWrapper.get())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (unsigned i = 0; i < data.size(); ++i)
|
||||
{
|
||||
CSMWorld::UniversalId::Type type = data[i].getType();
|
||||
if (mDisplay == CSMWorld::ColumnBase::Display_Referenceable)
|
||||
{
|
||||
if ( type == CSMWorld::UniversalId::Type_Activator
|
||||
|| type == CSMWorld::UniversalId::Type_Potion
|
||||
|| type == CSMWorld::UniversalId::Type_Apparatus
|
||||
|| type == CSMWorld::UniversalId::Type_Armor
|
||||
|| type == CSMWorld::UniversalId::Type_Book
|
||||
|| type == CSMWorld::UniversalId::Type_Clothing
|
||||
|| type == CSMWorld::UniversalId::Type_Container
|
||||
|| type == CSMWorld::UniversalId::Type_Creature
|
||||
|| type == CSMWorld::UniversalId::Type_Door
|
||||
|| type == CSMWorld::UniversalId::Type_Ingredient
|
||||
|| type == CSMWorld::UniversalId::Type_CreatureLevelledList
|
||||
|| type == CSMWorld::UniversalId::Type_ItemLevelledList
|
||||
|| type == CSMWorld::UniversalId::Type_Light
|
||||
|| type == CSMWorld::UniversalId::Type_Lockpick
|
||||
|| type == CSMWorld::UniversalId::Type_Miscellaneous
|
||||
|| type == CSMWorld::UniversalId::Type_Npc
|
||||
|| type == CSMWorld::UniversalId::Type_Probe
|
||||
|| type == CSMWorld::UniversalId::Type_Repair
|
||||
|| type == CSMWorld::UniversalId::Type_Static
|
||||
|| type == CSMWorld::UniversalId::Type_Weapon)
|
||||
{
|
||||
type = CSMWorld::UniversalId::Type_Referenceable;
|
||||
}
|
||||
}
|
||||
if (mDisplay == CSMWorld::TableMimeData::convertEnums(type))
|
||||
{
|
||||
emit tableMimeDataDropped(mEditor, mIndexWrapper->mIndex, data[i], document);
|
||||
emit editorDataCommited(mEditor, mIndexWrapper->mIndex, mDisplay);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
==============================DialogueDelegateDispatcher==========================================
|
||||
*/
|
||||
|
||||
CSVWorld::DialogueDelegateDispatcher::DialogueDelegateDispatcher(QObject* parent, CSMWorld::IdTable* table, QUndoStack& undoStack) :
|
||||
mParent(parent),
|
||||
mTable(table),
|
||||
mUndoStack(undoStack),
|
||||
mNotEditableDelegate(table, parent)
|
||||
{
|
||||
}
|
||||
|
||||
CSVWorld::CommandDelegate* CSVWorld::DialogueDelegateDispatcher::makeDelegate(CSMWorld::ColumnBase::Display display)
|
||||
{
|
||||
CommandDelegate *delegate = NULL;
|
||||
std::map<int, CommandDelegate*>::const_iterator delegateIt(mDelegates.find(display));
|
||||
if (delegateIt == mDelegates.end())
|
||||
{
|
||||
delegate = CommandDelegateFactoryCollection::get().makeDelegate (
|
||||
display, mUndoStack, mParent);
|
||||
mDelegates.insert(std::make_pair<int, CommandDelegate*>(display, delegate));
|
||||
} else
|
||||
{
|
||||
delegate = delegateIt->second;
|
||||
}
|
||||
return delegate;
|
||||
}
|
||||
|
||||
void CSVWorld::DialogueDelegateDispatcher::editorDataCommited(QWidget* editor, const QModelIndex& index, CSMWorld::ColumnBase::Display display)
|
||||
{
|
||||
setModelData(editor, mTable, index, display);
|
||||
}
|
||||
|
||||
void CSVWorld::DialogueDelegateDispatcher::setEditorData (QWidget* editor, const QModelIndex& index) const
|
||||
{
|
||||
CSMWorld::ColumnBase::Display display = static_cast<CSMWorld::ColumnBase::Display>
|
||||
(mTable->headerData (index.column(), Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt());
|
||||
|
||||
QLabel* label = qobject_cast<QLabel*>(editor);
|
||||
if(label)
|
||||
{
|
||||
mNotEditableDelegate.setEditorData(label, index);
|
||||
return;
|
||||
}
|
||||
|
||||
std::map<int, CommandDelegate*>::const_iterator delegateIt(mDelegates.find(display));
|
||||
if (delegateIt != mDelegates.end())
|
||||
{
|
||||
delegateIt->second->setEditorData(editor, index, true);
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < mProxys.size(); ++i)
|
||||
{
|
||||
if (mProxys[i]->getEditor() == editor)
|
||||
{
|
||||
mProxys[i]->setIndex(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSVWorld::DialogueDelegateDispatcher::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index, CSMWorld::ColumnBase::Display display) const
|
||||
{
|
||||
std::map<int, CommandDelegate*>::const_iterator delegateIt(mDelegates.find(display));
|
||||
if (delegateIt != mDelegates.end())
|
||||
{
|
||||
delegateIt->second->setModelData(editor, model, index);
|
||||
}
|
||||
}
|
||||
|
||||
void CSVWorld::DialogueDelegateDispatcher::paint (QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||
{
|
||||
//Does nothing
|
||||
}
|
||||
|
||||
QSize CSVWorld::DialogueDelegateDispatcher::sizeHint (const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||
{
|
||||
return QSize(); //silencing warning, otherwise does nothing
|
||||
}
|
||||
|
||||
QWidget* CSVWorld::DialogueDelegateDispatcher::makeEditor(CSMWorld::ColumnBase::Display display, const QModelIndex& index)
|
||||
{
|
||||
QVariant variant = index.data();
|
||||
if (!variant.isValid())
|
||||
{
|
||||
variant = index.data(Qt::DisplayRole);
|
||||
if (!variant.isValid())
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
QWidget* editor = NULL;
|
||||
if (! (mTable->flags (index) & Qt::ItemIsEditable))
|
||||
{
|
||||
return mNotEditableDelegate.createEditor(qobject_cast<QWidget*>(mParent), QStyleOptionViewItem(), index, display);
|
||||
}
|
||||
|
||||
std::map<int, CommandDelegate*>::iterator delegateIt(mDelegates.find(display));
|
||||
if (delegateIt != mDelegates.end())
|
||||
{
|
||||
editor = delegateIt->second->createEditor(qobject_cast<QWidget*>(mParent), QStyleOptionViewItem(), index, display);
|
||||
DialogueDelegateDispatcherProxy* proxy = new DialogueDelegateDispatcherProxy(editor, display);
|
||||
|
||||
bool skip = false;
|
||||
if (qobject_cast<DropLineEdit*>(editor))
|
||||
{
|
||||
connect(editor, SIGNAL(editingFinished()), proxy, SLOT(editorDataCommited()));
|
||||
connect(editor, SIGNAL(tableMimeDataDropped(const std::vector<CSMWorld::UniversalId>&, const CSMDoc::Document*)),
|
||||
proxy, SLOT(tableMimeDataDropped(const std::vector<CSMWorld::UniversalId>&, const CSMDoc::Document*)));
|
||||
connect(proxy, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*)),
|
||||
this, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*)));
|
||||
skip = true;
|
||||
}
|
||||
if(!skip && qobject_cast<QCheckBox*>(editor))
|
||||
{
|
||||
connect(editor, SIGNAL(stateChanged(int)), proxy, SLOT(editorDataCommited()));
|
||||
skip = true;
|
||||
}
|
||||
if(!skip && qobject_cast<QPlainTextEdit*>(editor))
|
||||
{
|
||||
connect(editor, SIGNAL(textChanged()), proxy, SLOT(editorDataCommited()));
|
||||
skip = true;
|
||||
}
|
||||
if(!skip && qobject_cast<QComboBox*>(editor))
|
||||
{
|
||||
connect(editor, SIGNAL(currentIndexChanged (int)), proxy, SLOT(editorDataCommited()));
|
||||
skip = true;
|
||||
}
|
||||
if(!skip && qobject_cast<QAbstractSpinBox*>(editor))
|
||||
{
|
||||
connect(editor, SIGNAL(editingFinished()), proxy, SLOT(editorDataCommited()));
|
||||
skip = true;
|
||||
}
|
||||
|
||||
connect(proxy, SIGNAL(editorDataCommited(QWidget*, const QModelIndex&, CSMWorld::ColumnBase::Display)), this, SLOT(editorDataCommited(QWidget*, const QModelIndex&, CSMWorld::ColumnBase::Display)));
|
||||
mProxys.push_back(proxy); //deleted in the destructor
|
||||
}
|
||||
return editor;
|
||||
}
|
||||
|
||||
CSVWorld::DialogueDelegateDispatcher::~DialogueDelegateDispatcher()
|
||||
{
|
||||
for (unsigned i = 0; i < mProxys.size(); ++i)
|
||||
{
|
||||
delete mProxys[i]; //unique_ptr could be handy
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=============================================================EditWidget=====================================================
|
||||
*/
|
||||
|
||||
CSVWorld::EditWidget::EditWidget(QWidget *parent, int row, CSMWorld::IdTable* table, QUndoStack& undoStack, bool createAndDelete) :
|
||||
mDispatcher(this, table, undoStack),
|
||||
QScrollArea(parent),
|
||||
mWidgetMapper(NULL),
|
||||
mMainWidget(NULL),
|
||||
mUndoStack(undoStack),
|
||||
mTable(table)
|
||||
{
|
||||
remake (row);
|
||||
connect(&mDispatcher, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*)), this, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*)));
|
||||
}
|
||||
|
||||
void CSVWorld::EditWidget::remake(int row)
|
||||
{
|
||||
if (mMainWidget)
|
||||
{
|
||||
delete mMainWidget;
|
||||
}
|
||||
mMainWidget = new QWidget (this);
|
||||
|
||||
//not sure if widget mapper can handle deleting the widgets that were mapped
|
||||
if (mWidgetMapper)
|
||||
{
|
||||
delete mWidgetMapper;
|
||||
}
|
||||
mWidgetMapper = new QDataWidgetMapper (this);
|
||||
mWidgetMapper->setModel(mTable);
|
||||
mWidgetMapper->setItemDelegate(&mDispatcher);
|
||||
|
||||
QFrame* line = new QFrame(mMainWidget);
|
||||
line->setObjectName(QString::fromUtf8("line"));
|
||||
line->setGeometry(QRect(320, 150, 118, 3));
|
||||
line->setFrameShape(QFrame::HLine);
|
||||
line->setFrameShadow(QFrame::Sunken);
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout(mMainWidget);
|
||||
QGridLayout *unlockedLayout = new QGridLayout();
|
||||
QGridLayout *lockedLayout = new QGridLayout();
|
||||
mainLayout->addLayout(lockedLayout, 0);
|
||||
mainLayout->addWidget(line, 1);
|
||||
mainLayout->addLayout(unlockedLayout, 2);
|
||||
mainLayout->addStretch(1);
|
||||
|
||||
int unlocked = 0;
|
||||
int locked = 0;
|
||||
const int columns = mTable->columnCount();
|
||||
for (int i=0; i<columns; ++i)
|
||||
{
|
||||
int flags = mTable->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Flags).toInt();
|
||||
|
||||
if (flags & CSMWorld::ColumnBase::Flag_Dialogue)
|
||||
{
|
||||
CSMWorld::ColumnBase::Display display = static_cast<CSMWorld::ColumnBase::Display>
|
||||
(mTable->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt());
|
||||
|
||||
mDispatcher.makeDelegate(display);
|
||||
QWidget *editor = mDispatcher.makeEditor(display, (mTable->index (row, i)));
|
||||
|
||||
if (editor)
|
||||
{
|
||||
mWidgetMapper->addMapping (editor, i);
|
||||
QLabel* label = new QLabel(mTable->headerData (i, Qt::Horizontal).toString(), mMainWidget);
|
||||
label->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
editor->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
|
||||
if (! (mTable->flags (mTable->index (row, i)) & Qt::ItemIsEditable))
|
||||
{
|
||||
lockedLayout->addWidget (label, locked, 0);
|
||||
lockedLayout->addWidget (editor, locked, 1);
|
||||
++locked;
|
||||
} else
|
||||
{
|
||||
unlockedLayout->addWidget (label, unlocked, 0);
|
||||
unlockedLayout->addWidget (editor, unlocked, 1);
|
||||
++unlocked;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mWidgetMapper->setCurrentModelIndex(mTable->index(row, 0));
|
||||
|
||||
this->setMinimumWidth(325); //TODO find better way to set the width or make it customizable
|
||||
this->setWidget(mMainWidget);
|
||||
this->setWidgetResizable(true);
|
||||
}
|
||||
|
||||
/*
|
||||
==============================DialogueSubView==========================================
|
||||
*/
|
||||
|
||||
CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document,
|
||||
const CreatorFactoryBase& creatorFactory, bool sorting) :
|
||||
|
||||
SubView (id),
|
||||
mEditWidget(0),
|
||||
mMainLayout(NULL),
|
||||
mUndoStack(document.getUndoStack()),
|
||||
mTable(dynamic_cast<CSMWorld::IdTable*>(document.getData().getTableModel(id))),
|
||||
mRow (-1),
|
||||
mLocked(false),
|
||||
mDocument(document)
|
||||
|
||||
{
|
||||
connect(mTable, SIGNAL(dataChanged (const QModelIndex&, const QModelIndex&)), this, SLOT(dataChanged(const QModelIndex&)));
|
||||
mRow = mTable->getModelIndex (id.getId(), 0).row();
|
||||
QWidget *mainWidget = new QWidget(this);
|
||||
|
||||
QHBoxLayout *buttonsLayout = new QHBoxLayout;
|
||||
QToolButton* prevButton = new QToolButton(mainWidget);
|
||||
prevButton->setIcon(QIcon(":/go-previous.png"));
|
||||
QToolButton* nextButton = new QToolButton(mainWidget);
|
||||
nextButton->setIcon(QIcon(":/go-next.png"));
|
||||
buttonsLayout->addWidget(prevButton, 0);
|
||||
buttonsLayout->addWidget(nextButton, 1);
|
||||
buttonsLayout->addStretch(2);
|
||||
|
||||
QToolButton* cloneButton = new QToolButton(mainWidget);
|
||||
cloneButton->setIcon(QIcon(":/edit-clone.png"));
|
||||
QToolButton* addButton = new QToolButton(mainWidget);
|
||||
addButton->setIcon(QIcon(":/add.png"));
|
||||
QToolButton* deleteButton = new QToolButton(mainWidget);
|
||||
deleteButton->setIcon(QIcon(":/edit-delete.png"));
|
||||
QToolButton* revertButton = new QToolButton(mainWidget);
|
||||
revertButton->setIcon(QIcon(":/edit-undo.png"));
|
||||
|
||||
if (mTable->hasPreview())
|
||||
{
|
||||
QToolButton* previewButton = new QToolButton(mainWidget);
|
||||
previewButton->setIcon(QIcon(":/edit-preview.png"));
|
||||
buttonsLayout->addWidget(previewButton);
|
||||
connect(previewButton, SIGNAL(clicked()), this, SLOT(showPreview()));
|
||||
}
|
||||
|
||||
if (mTable->getViewing()!=CSMWorld::IdTable::Viewing_None)
|
||||
{
|
||||
QToolButton* viewButton = new QToolButton(mainWidget);
|
||||
viewButton->setIcon(QIcon(":/cell.png"));
|
||||
buttonsLayout->addWidget(viewButton);
|
||||
connect(viewButton, SIGNAL(clicked()), this, SLOT(viewRecord()));
|
||||
}
|
||||
|
||||
buttonsLayout->addWidget(cloneButton);
|
||||
buttonsLayout->addWidget(addButton);
|
||||
buttonsLayout->addWidget(deleteButton);
|
||||
buttonsLayout->addWidget(revertButton);
|
||||
|
||||
connect(nextButton, SIGNAL(clicked()), this, SLOT(nextId()));
|
||||
connect(prevButton, SIGNAL(clicked()), this, SLOT(prevId()));
|
||||
connect(cloneButton, SIGNAL(clicked()), this, SLOT(cloneRequest()));
|
||||
connect(revertButton, SIGNAL(clicked()), this, SLOT(revertRecord()));
|
||||
connect(deleteButton, SIGNAL(clicked()), this, SLOT(deleteRecord()));
|
||||
|
||||
mMainLayout = new QVBoxLayout(mainWidget);
|
||||
|
||||
mEditWidget = new EditWidget(mainWidget, mRow, mTable, mUndoStack, false);
|
||||
connect(mEditWidget, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*)),
|
||||
this, SLOT(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*)));
|
||||
|
||||
mMainLayout->addWidget(mEditWidget);
|
||||
mEditWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
|
||||
|
||||
mMainLayout->addWidget (mBottom =
|
||||
new TableBottomBox (creatorFactory, document.getData(), document.getUndoStack(), id, this));
|
||||
|
||||
mBottom->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed);
|
||||
connect(mBottom, SIGNAL(requestFocus(const std::string&)), this, SLOT(requestFocus(const std::string&)));
|
||||
connect(addButton, SIGNAL(clicked()), mBottom, SLOT(createRequest()));
|
||||
|
||||
if(!mBottom->canCreateAndDelete())
|
||||
{
|
||||
cloneButton->setDisabled(true);
|
||||
addButton->setDisabled(true);
|
||||
deleteButton->setDisabled(true);
|
||||
}
|
||||
|
||||
dataChanged(mTable->index(mRow, 0));
|
||||
mMainLayout->addLayout(buttonsLayout);
|
||||
setWidget(mainWidget);
|
||||
}
|
||||
|
||||
void CSVWorld::DialogueSubView::prevId()
|
||||
{
|
||||
int newRow = mRow - 1;
|
||||
if (newRow < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
while (newRow >= 0)
|
||||
{
|
||||
QModelIndex newIndex(mTable->index(newRow, 0));
|
||||
|
||||
if (!newIndex.isValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CSMWorld::RecordBase::State state = static_cast<CSMWorld::RecordBase::State>(mTable->data (mTable->index (newRow, 1)).toInt());
|
||||
if (!(state == CSMWorld::RecordBase::State_Deleted || state == CSMWorld::RecordBase::State_Erased))
|
||||
{
|
||||
mEditWidget->remake(newRow);
|
||||
setUniversalId(CSMWorld::UniversalId (static_cast<CSMWorld::UniversalId::Type> (mTable->data (mTable->index (newRow, 2)).toInt()),
|
||||
mTable->data (mTable->index (newRow, 0)).toString().toUtf8().constData()));
|
||||
mRow = newRow;
|
||||
mEditWidget->setDisabled(mLocked);
|
||||
return;
|
||||
}
|
||||
--newRow;
|
||||
}
|
||||
}
|
||||
|
||||
void CSVWorld::DialogueSubView::nextId()
|
||||
{
|
||||
int newRow = mRow + 1;
|
||||
|
||||
if (newRow >= mTable->rowCount())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
while (newRow < mTable->rowCount())
|
||||
{
|
||||
QModelIndex newIndex(mTable->index(newRow, 0));
|
||||
|
||||
if (!newIndex.isValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CSMWorld::RecordBase::State state = static_cast<CSMWorld::RecordBase::State>(mTable->data (mTable->index (newRow, 1)).toInt());
|
||||
if (!(state == CSMWorld::RecordBase::State_Deleted || state == CSMWorld::RecordBase::State_Erased))
|
||||
{
|
||||
mEditWidget->remake(newRow);
|
||||
setUniversalId(CSMWorld::UniversalId (static_cast<CSMWorld::UniversalId::Type> (mTable->data (mTable->index (newRow, 2)).toInt()),
|
||||
mTable->data (mTable->index (newRow, 0)).toString().toUtf8().constData()));
|
||||
mRow = newRow;
|
||||
mEditWidget->setDisabled(mLocked);
|
||||
return;
|
||||
}
|
||||
++newRow;
|
||||
}
|
||||
}
|
||||
|
||||
void CSVWorld::DialogueSubView::setEditLock (bool locked)
|
||||
{
|
||||
mLocked = locked;
|
||||
CSMWorld::RecordBase::State state = static_cast<CSMWorld::RecordBase::State>(mTable->data (mTable->index (mRow, 1)).toInt());
|
||||
if (state == CSMWorld::RecordBase::State_Deleted || state == CSMWorld::RecordBase::State_Erased)
|
||||
{
|
||||
mEditWidget->setDisabled(true);
|
||||
} else
|
||||
{
|
||||
mEditWidget->setDisabled(mLocked);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
void CSVWorld::DialogueSubView::dataChanged(const QModelIndex & index)
|
||||
{
|
||||
if (index.row() == mRow)
|
||||
{
|
||||
CSMWorld::RecordBase::State state = static_cast<CSMWorld::RecordBase::State>(mTable->data (mTable->index (mRow, 1)).toInt());
|
||||
if (state == CSMWorld::RecordBase::State_Deleted || state == CSMWorld::RecordBase::State_Erased)
|
||||
{
|
||||
mEditWidget->setDisabled(true);
|
||||
} else
|
||||
{
|
||||
mEditWidget->setDisabled(mLocked);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSVWorld::DialogueSubView::tableMimeDataDropped(QWidget* editor,
|
||||
const QModelIndex& index,
|
||||
const CSMWorld::UniversalId& id,
|
||||
const CSMDoc::Document* document)
|
||||
{
|
||||
if (document == &mDocument)
|
||||
{
|
||||
qobject_cast<DropLineEdit*>(editor)->setText(id.getId().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void CSVWorld::DialogueSubView::revertRecord()
|
||||
{
|
||||
int rows = mTable->rowCount();
|
||||
if (!mLocked && mTable->columnCount() > 0 && mRow < mTable->rowCount() )
|
||||
{
|
||||
CSMWorld::RecordBase::State state =
|
||||
static_cast<CSMWorld::RecordBase::State> (mTable->data (mTable->index (mRow, 1)).toInt());
|
||||
|
||||
if (state!=CSMWorld::RecordBase::State_BaseOnly)
|
||||
{
|
||||
mUndoStack.push(new CSMWorld::RevertCommand(*mTable, mTable->data(mTable->index (mRow, 0)).toString().toUtf8().constData()));
|
||||
}
|
||||
if (rows != mTable->rowCount())
|
||||
{
|
||||
if (mTable->rowCount() == 0)
|
||||
{
|
||||
mEditWidget->setDisabled(true); //closing the editor is other option
|
||||
return;
|
||||
}
|
||||
if (mRow >= mTable->rowCount())
|
||||
{
|
||||
prevId();
|
||||
} else {
|
||||
dataChanged(mTable->index(mRow, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSVWorld::DialogueSubView::deleteRecord()
|
||||
{
|
||||
int rows = mTable->rowCount();
|
||||
|
||||
//easier than disabling the button
|
||||
CSMWorld::RecordBase::State state = static_cast<CSMWorld::RecordBase::State>(mTable->data (mTable->index (mRow, 1)).toInt());
|
||||
bool deledetedOrErased = (state == CSMWorld::RecordBase::State_Deleted || state == CSMWorld::RecordBase::State_Erased);
|
||||
|
||||
if (!mLocked &&
|
||||
mTable->columnCount() > 0 &&
|
||||
!deledetedOrErased &&
|
||||
mRow < rows &&
|
||||
mBottom->canCreateAndDelete())
|
||||
{
|
||||
mUndoStack.push(new CSMWorld::DeleteCommand(*mTable, mTable->data(mTable->index (mRow, 0)).toString().toUtf8().constData()));
|
||||
if (rows != mTable->rowCount())
|
||||
{
|
||||
if (mTable->rowCount() == 0)
|
||||
{
|
||||
mEditWidget->setDisabled(true); //closing the editor is other option
|
||||
return;
|
||||
}
|
||||
if (mRow >= mTable->rowCount())
|
||||
{
|
||||
prevId();
|
||||
} else {
|
||||
dataChanged(mTable->index(mRow, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSVWorld::DialogueSubView::requestFocus (const std::string& id)
|
||||
{
|
||||
mRow = mTable->getModelIndex (id, 0).row();
|
||||
mEditWidget->remake(mRow);
|
||||
}
|
||||
|
||||
void CSVWorld::DialogueSubView::cloneRequest ()
|
||||
{
|
||||
mBottom->cloneRequest(mTable->data(mTable->index (mRow, 0)).toString().toUtf8().constData(),
|
||||
static_cast<CSMWorld::UniversalId::Type>(mTable->data(mTable->index(mRow, 2)).toInt()));
|
||||
}
|
||||
|
||||
void CSVWorld::DialogueSubView::showPreview ()
|
||||
{
|
||||
if (mTable->hasPreview() && mRow < mTable->rowCount())
|
||||
{
|
||||
emit focusId(CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Preview, mTable->data(mTable->index (mRow, 0)).toString().toUtf8().constData()), "");
|
||||
}
|
||||
}
|
||||
|
||||
void CSVWorld::DialogueSubView::viewRecord()
|
||||
{
|
||||
if (mRow < mTable->rowCount())
|
||||
{
|
||||
std::pair<CSMWorld::UniversalId, std::string> params = mTable->view (mRow);
|
||||
|
||||
if (params.first.getType()!=CSMWorld::UniversalId::Type_None)
|
||||
emit focusId (params.first, params.second);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,25 @@
|
|||
#ifndef CSV_WORLD_DIALOGUESUBVIEW_H
|
||||
#define CSV_WORLD_DIALOGUESUBVIEW_H
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
#include <QAbstractItemDelegate>
|
||||
#include <QScrollArea>
|
||||
|
||||
#include "../doc/subview.hpp"
|
||||
#include "../../model/world/columnbase.hpp"
|
||||
|
||||
class QDataWidgetMapper;
|
||||
class QSize;
|
||||
class QEvent;
|
||||
class QLabel;
|
||||
class QVBoxLayout;
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class IdTable;
|
||||
}
|
||||
|
||||
namespace CSMDoc
|
||||
{
|
||||
|
@ -12,15 +28,181 @@ namespace CSMDoc
|
|||
|
||||
namespace CSVWorld
|
||||
{
|
||||
class DialogueSubView : public CSVDoc::SubView
|
||||
class CommandDelegate;
|
||||
class CreatorFactoryBase;
|
||||
class TableBottomBox;
|
||||
|
||||
class NotEditableSubDelegate : public QAbstractItemDelegate
|
||||
{
|
||||
const CSMWorld::IdTable* mTable;
|
||||
public:
|
||||
NotEditableSubDelegate(const CSMWorld::IdTable* table, QObject * parent = 0);
|
||||
|
||||
virtual void setEditorData (QLabel* editor, const QModelIndex& index) const;
|
||||
|
||||
virtual void setModelData (QWidget* editor, QAbstractItemModel* model, const QModelIndex& index, CSMWorld::ColumnBase::Display display) const;
|
||||
|
||||
virtual void paint (QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
|
||||
///< does nothing
|
||||
|
||||
virtual QSize sizeHint (const QStyleOptionViewItem& option, const QModelIndex& index) const;
|
||||
///< does nothing
|
||||
|
||||
virtual QWidget *createEditor (QWidget *parent,
|
||||
const QStyleOptionViewItem& option,
|
||||
const QModelIndex& index,
|
||||
CSMWorld::ColumnBase::Display display = CSMWorld::ColumnBase::Display_None) const;
|
||||
};
|
||||
|
||||
//this can't be nested into the DialogueDelegateDispatcher, because it needs to emit signals
|
||||
class DialogueDelegateDispatcherProxy : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
class refWrapper
|
||||
{
|
||||
public:
|
||||
refWrapper(const QModelIndex& index);
|
||||
|
||||
const QModelIndex& mIndex;
|
||||
};
|
||||
|
||||
QWidget* mEditor;
|
||||
|
||||
CSMWorld::ColumnBase::Display mDisplay;
|
||||
|
||||
std::auto_ptr<refWrapper> mIndexWrapper;
|
||||
|
||||
public:
|
||||
DialogueDelegateDispatcherProxy(QWidget* editor, CSMWorld::ColumnBase::Display display);
|
||||
QWidget* getEditor() const;
|
||||
|
||||
public slots:
|
||||
void editorDataCommited();
|
||||
void setIndex(const QModelIndex& index);
|
||||
void tableMimeDataDropped(const std::vector<CSMWorld::UniversalId>& data, const CSMDoc::Document* document);
|
||||
|
||||
signals:
|
||||
void editorDataCommited(QWidget* editor, const QModelIndex& index, CSMWorld::ColumnBase::Display display);
|
||||
|
||||
void tableMimeDataDropped(QWidget* editor, const QModelIndex& index,
|
||||
const CSMWorld::UniversalId& id,
|
||||
const CSMDoc::Document* document);
|
||||
|
||||
};
|
||||
|
||||
class DialogueDelegateDispatcher : public QAbstractItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
std::map<int, CommandDelegate*> mDelegates;
|
||||
|
||||
QObject* mParent;
|
||||
|
||||
CSMWorld::IdTable* mTable;
|
||||
|
||||
QUndoStack& mUndoStack;
|
||||
|
||||
NotEditableSubDelegate mNotEditableDelegate;
|
||||
|
||||
std::vector<DialogueDelegateDispatcherProxy*> mProxys; //once we move to the C++11 we should use unique_ptr
|
||||
|
||||
public:
|
||||
DialogueDelegateDispatcher(QObject* parent, CSMWorld::IdTable* table, QUndoStack& undoStack);
|
||||
|
||||
~DialogueDelegateDispatcher();
|
||||
|
||||
CSVWorld::CommandDelegate* makeDelegate(CSMWorld::ColumnBase::Display display);
|
||||
|
||||
QWidget* makeEditor(CSMWorld::ColumnBase::Display display, const QModelIndex& index);
|
||||
///< will return null if delegate is not present, parent of the widget is same as for dispatcher itself
|
||||
|
||||
virtual void setEditorData (QWidget* editor, const QModelIndex& index) const;
|
||||
|
||||
virtual void setModelData (QWidget* editor, QAbstractItemModel* model, const QModelIndex& index, CSMWorld::ColumnBase::Display display) const;
|
||||
|
||||
virtual void paint (QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
|
||||
///< does nothing
|
||||
|
||||
virtual QSize sizeHint (const QStyleOptionViewItem& option, const QModelIndex& index) const;
|
||||
///< does nothing
|
||||
|
||||
private slots:
|
||||
void editorDataCommited(QWidget* editor, const QModelIndex& index, CSMWorld::ColumnBase::Display display);
|
||||
|
||||
signals:
|
||||
void tableMimeDataDropped(QWidget* editor, const QModelIndex& index,
|
||||
const CSMWorld::UniversalId& id,
|
||||
const CSMDoc::Document* document);
|
||||
|
||||
|
||||
};
|
||||
|
||||
class EditWidget : public QScrollArea
|
||||
{
|
||||
Q_OBJECT
|
||||
QDataWidgetMapper *mWidgetMapper;
|
||||
DialogueDelegateDispatcher mDispatcher;
|
||||
QWidget* mMainWidget;
|
||||
CSMWorld::IdTable* mTable;
|
||||
QUndoStack& mUndoStack;
|
||||
|
||||
public:
|
||||
|
||||
DialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document, bool createAndDelete);
|
||||
EditWidget (QWidget *parent, int row, CSMWorld::IdTable* table, QUndoStack& undoStack, bool createAndDelete = false);
|
||||
|
||||
void remake(int row);
|
||||
|
||||
signals:
|
||||
void tableMimeDataDropped(QWidget* editor, const QModelIndex& index,
|
||||
const CSMWorld::UniversalId& id,
|
||||
const CSMDoc::Document* document);
|
||||
};
|
||||
|
||||
class DialogueSubView : public CSVDoc::SubView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
EditWidget* mEditWidget;
|
||||
QVBoxLayout* mMainLayout;
|
||||
CSMWorld::IdTable* mTable;
|
||||
QUndoStack& mUndoStack;
|
||||
int mRow;
|
||||
bool mLocked;
|
||||
const CSMDoc::Document& mDocument;
|
||||
TableBottomBox* mBottom;
|
||||
|
||||
public:
|
||||
|
||||
DialogueSubView (const CSMWorld::UniversalId& id,
|
||||
CSMDoc::Document& document,
|
||||
const CreatorFactoryBase& creatorFactory,
|
||||
bool sorting = false);
|
||||
|
||||
virtual void setEditLock (bool locked);
|
||||
|
||||
private slots:
|
||||
|
||||
void nextId();
|
||||
|
||||
void prevId();
|
||||
|
||||
void showPreview();
|
||||
|
||||
void viewRecord();
|
||||
|
||||
void revertRecord();
|
||||
|
||||
void deleteRecord();
|
||||
|
||||
void cloneRequest();
|
||||
|
||||
void dataChanged(const QModelIndex & index);
|
||||
///\brief we need to care for deleting currently edited record
|
||||
|
||||
void tableMimeDataDropped(QWidget* editor, const QModelIndex& index,
|
||||
const CSMWorld::UniversalId& id,
|
||||
const CSMDoc::Document* document);
|
||||
|
||||
void requestFocus (const std::string& id);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -41,10 +41,18 @@ CSVWorld::EnumDelegate::EnumDelegate (const std::vector<std::pair<int, QString>
|
|||
|
||||
}
|
||||
|
||||
QWidget *CSVWorld::EnumDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem& option,
|
||||
const QModelIndex& index) const
|
||||
QWidget *CSVWorld::EnumDelegate::createEditor(QWidget *parent,
|
||||
const QStyleOptionViewItem& option,
|
||||
const QModelIndex& index) const
|
||||
{
|
||||
if (!index.data().isValid())
|
||||
return createEditor(parent, option, index, CSMWorld::ColumnBase::Display_None);
|
||||
//overloading virtual functions is HARD
|
||||
}
|
||||
|
||||
QWidget *CSVWorld::EnumDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem& option,
|
||||
const QModelIndex& index, CSMWorld::ColumnBase::Display display) const
|
||||
{
|
||||
if (!index.data(Qt::EditRole).isValid() && !index.data(Qt::DisplayRole).isValid())
|
||||
return 0;
|
||||
|
||||
QComboBox *comboBox = new QComboBox (parent);
|
||||
|
@ -56,11 +64,22 @@ QWidget *CSVWorld::EnumDelegate::createEditor(QWidget *parent, const QStyleOptio
|
|||
return comboBox;
|
||||
}
|
||||
|
||||
void CSVWorld::EnumDelegate::setEditorData (QWidget *editor, const QModelIndex& index) const
|
||||
void CSVWorld::EnumDelegate::setEditorData (QWidget *editor, const QModelIndex& index, bool tryDisplay) const
|
||||
{
|
||||
if (QComboBox *comboBox = dynamic_cast<QComboBox *> (editor))
|
||||
{
|
||||
int value = index.data (Qt::EditRole).toInt();
|
||||
QVariant data = index.data (Qt::EditRole);
|
||||
|
||||
if (tryDisplay && !data.isValid())
|
||||
{
|
||||
data = index.data (Qt::DisplayRole);
|
||||
if (!data.isValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int value = data.toInt();
|
||||
|
||||
std::size_t size = mValues.size();
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <vector>
|
||||
|
||||
#include <QString>
|
||||
#include <QStyledItemDelegate>
|
||||
|
||||
#include <components/esm/defs.hpp>
|
||||
|
||||
|
@ -31,10 +32,16 @@ namespace CSVWorld
|
|||
EnumDelegate (const std::vector<std::pair<int, QString> >& values,
|
||||
QUndoStack& undoStack, QObject *parent);
|
||||
|
||||
virtual QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem& option,
|
||||
const QModelIndex& index) const;
|
||||
virtual QWidget *createEditor(QWidget *parent,
|
||||
const QStyleOptionViewItem& option,
|
||||
const QModelIndex& index) const;
|
||||
|
||||
virtual void setEditorData (QWidget *editor, const QModelIndex& index) const;
|
||||
virtual QWidget *createEditor(QWidget *parent,
|
||||
const QStyleOptionViewItem& option,
|
||||
const QModelIndex& index,
|
||||
CSMWorld::ColumnBase::Display display = CSMWorld::ColumnBase::Display_None) const;
|
||||
|
||||
virtual void setEditorData (QWidget *editor, const QModelIndex& index, bool tryDisplay = false) const;
|
||||
|
||||
virtual void paint (QPainter *painter, const QStyleOptionViewItem& option,
|
||||
const QModelIndex& index) const;
|
||||
|
|
64
apps/opencs/view/world/previewsubview.cpp
Normal file
64
apps/opencs/view/world/previewsubview.cpp
Normal file
|
@ -0,0 +1,64 @@
|
|||
|
||||
#include "previewsubview.hpp"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
|
||||
#include "../render/previewwidget.hpp"
|
||||
|
||||
#include "scenetoolbar.hpp"
|
||||
#include "scenetoolmode.hpp"
|
||||
|
||||
CSVWorld::PreviewSubView::PreviewSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document)
|
||||
: SubView (id)
|
||||
{
|
||||
QHBoxLayout *layout = new QHBoxLayout;
|
||||
|
||||
layout->setContentsMargins (QMargins (0, 0, 0, 0));
|
||||
|
||||
if (document.getData().getReferenceables().searchId (id.getId())==-1)
|
||||
{
|
||||
std::string referenceableId =
|
||||
document.getData().getReferences().getRecord (id.getId()).get().mRefID;
|
||||
|
||||
referenceableIdChanged (referenceableId);
|
||||
|
||||
mScene =
|
||||
new CSVRender::PreviewWidget (document.getData(), referenceableId, id.getId(), this);
|
||||
}
|
||||
else
|
||||
mScene = new CSVRender::PreviewWidget (document.getData(), id.getId(), this);
|
||||
|
||||
SceneToolbar *toolbar = new SceneToolbar (48, this);
|
||||
|
||||
SceneToolMode *lightingTool = mScene->makeLightingSelector (toolbar);
|
||||
toolbar->addTool (lightingTool);
|
||||
|
||||
layout->addWidget (toolbar, 0);
|
||||
|
||||
layout->addWidget (mScene, 1);
|
||||
|
||||
QWidget *widget = new QWidget;
|
||||
|
||||
widget->setLayout (layout);
|
||||
|
||||
setWidget (widget);
|
||||
|
||||
connect (mScene, SIGNAL (closeRequest()), this, SLOT (closeRequest()));
|
||||
connect (mScene, SIGNAL (referenceableIdChanged (const std::string&)),
|
||||
this, SLOT (referenceableIdChanged (const std::string&)));
|
||||
}
|
||||
|
||||
void CSVWorld::PreviewSubView::setEditLock (bool locked) {}
|
||||
|
||||
void CSVWorld::PreviewSubView::closeRequest()
|
||||
{
|
||||
deleteLater();
|
||||
}
|
||||
|
||||
void CSVWorld::PreviewSubView::referenceableIdChanged (const std::string& id)
|
||||
{
|
||||
if (id.empty())
|
||||
setWindowTitle ("Preview: Reference to <nothing>");
|
||||
else
|
||||
setWindowTitle (("Preview: Reference to " + id).c_str());
|
||||
}
|
38
apps/opencs/view/world/previewsubview.hpp
Normal file
38
apps/opencs/view/world/previewsubview.hpp
Normal file
|
@ -0,0 +1,38 @@
|
|||
#ifndef CSV_WORLD_PREVIEWSUBVIEW_H
|
||||
#define CSV_WORLD_PREVIEWSUBVIEW_H
|
||||
|
||||
#include "../doc/subview.hpp"
|
||||
|
||||
namespace CSMDoc
|
||||
{
|
||||
class Document;
|
||||
}
|
||||
|
||||
namespace CSVRender
|
||||
{
|
||||
class PreviewWidget;
|
||||
}
|
||||
|
||||
namespace CSVWorld
|
||||
{
|
||||
class PreviewSubView : public CSVDoc::SubView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
CSVRender::PreviewWidget *mScene;
|
||||
|
||||
public:
|
||||
|
||||
PreviewSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document);
|
||||
|
||||
virtual void setEditLock (bool locked);
|
||||
|
||||
private slots:
|
||||
|
||||
void closeRequest();
|
||||
|
||||
void referenceableIdChanged (const std::string& id);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -34,13 +34,16 @@ CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::D
|
|||
|
||||
SceneToolbar *toolbar = new SceneToolbar (48, this);
|
||||
|
||||
if (id.getId()[0]=='#')
|
||||
if (id.getId()=="sys::default")
|
||||
mScene = new CSVRender::PagedWorldspaceWidget (this);
|
||||
else
|
||||
mScene = new CSVRender::UnpagedWorldspaceWidget (id.getId(), document, this);
|
||||
|
||||
SceneToolMode *tool = mScene->makeNavigationSelector (toolbar);
|
||||
toolbar->addTool (tool);
|
||||
SceneToolMode *navigationTool = mScene->makeNavigationSelector (toolbar);
|
||||
toolbar->addTool (navigationTool);
|
||||
|
||||
SceneToolMode *lightingTool = mScene->makeLightingSelector (toolbar);
|
||||
toolbar->addTool (lightingTool);
|
||||
|
||||
layout2->addWidget (toolbar, 0);
|
||||
|
||||
|
|
|
@ -71,9 +71,9 @@ void CSVWorld::ScriptEdit::dropEvent (QDropEvent* event)
|
|||
{
|
||||
if (stringNeedsQuote(it->getId()))
|
||||
{
|
||||
insertPlainText(QString::fromStdString ('"' + it->getId() + '"'));
|
||||
insertPlainText(QString::fromUtf8 (('"' + it->getId() + '"').c_str()));
|
||||
} else {
|
||||
insertPlainText(QString::fromStdString (it->getId()));
|
||||
insertPlainText(QString::fromUtf8 (it->getId().c_str()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ void CSVWorld::ScriptEdit::dropEvent (QDropEvent* event)
|
|||
|
||||
bool CSVWorld::ScriptEdit::stringNeedsQuote (const std::string& id) const
|
||||
{
|
||||
const QString string(QString::fromStdString(id)); //<regex> is only for c++11, so let's use qregexp for now.
|
||||
const QString string(QString::fromUtf8(id.c_str())); //<regex> is only for c++11, so let's use qregexp for now.
|
||||
//I'm not quite sure when do we need to put quotes. To be safe we will use quotes for anything other than…
|
||||
return !(string.contains(mWhiteListQoutes));
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "scenesubview.hpp"
|
||||
#include "dialoguecreator.hpp"
|
||||
#include "infocreator.hpp"
|
||||
#include "previewsubview.hpp"
|
||||
|
||||
void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
|
||||
{
|
||||
|
@ -78,4 +79,62 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
|
|||
CreatorFactory<CSVFilter::FilterCreator> >);
|
||||
|
||||
manager.add (CSMWorld::UniversalId::Type_Scene, new CSVDoc::SubViewFactory<SceneSubView>);
|
||||
|
||||
//edit subviews
|
||||
manager.add (CSMWorld::UniversalId::Type_Region,
|
||||
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<GenericCreator> > (false));
|
||||
|
||||
manager.add (CSMWorld::UniversalId::Type_Spell,
|
||||
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<GenericCreator> > (false));
|
||||
|
||||
manager.add (CSMWorld::UniversalId::Type_Referenceable,
|
||||
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<ReferenceableCreator> > (false));
|
||||
|
||||
manager.add (CSMWorld::UniversalId::Type_Birthsign,
|
||||
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<GenericCreator> > (false));
|
||||
|
||||
manager.add (CSMWorld::UniversalId::Type_Global,
|
||||
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<GenericCreator> > (false));
|
||||
|
||||
manager.add (CSMWorld::UniversalId::Type_Gmst,
|
||||
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<GenericCreator> > (false));
|
||||
|
||||
manager.add (CSMWorld::UniversalId::Type_Race,
|
||||
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<GenericCreator> > (false));
|
||||
|
||||
manager.add (CSMWorld::UniversalId::Type_Class,
|
||||
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<GenericCreator> > (false));
|
||||
|
||||
manager.add (CSMWorld::UniversalId::Type_Reference,
|
||||
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<ReferenceCreator> > (false));
|
||||
|
||||
manager.add (CSMWorld::UniversalId::Type_Cell,
|
||||
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<CellCreator> > (false));
|
||||
|
||||
manager.add (CSMWorld::UniversalId::Type_Filter,
|
||||
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<GenericCreator> > (false));
|
||||
|
||||
manager.add (CSMWorld::UniversalId::Type_Sound,
|
||||
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<GenericCreator> > (false));
|
||||
|
||||
manager.add (CSMWorld::UniversalId::Type_Faction,
|
||||
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<GenericCreator> > (false));
|
||||
|
||||
manager.add (CSMWorld::UniversalId::Type_Skill,
|
||||
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<GenericCreator> > (false));
|
||||
|
||||
manager.add (CSMWorld::UniversalId::Type_JournalInfo,
|
||||
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<InfoCreator> > (false));
|
||||
|
||||
manager.add (CSMWorld::UniversalId::Type_TopicInfo,
|
||||
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, CreatorFactory<InfoCreator> >(false));
|
||||
|
||||
manager.add (CSMWorld::UniversalId::Type_Topic,
|
||||
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, TopicCreatorFactory> (false));
|
||||
|
||||
manager.add (CSMWorld::UniversalId::Type_Journal,
|
||||
new CSVDoc::SubViewFactoryWithCreator<DialogueSubView, JournalCreatorFactory> (false));
|
||||
|
||||
//preview
|
||||
manager.add (CSMWorld::UniversalId::Type_Preview, new CSVDoc::SubViewFactory<PreviewSubView>);
|
||||
}
|
|
@ -39,18 +39,6 @@ void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event)
|
|||
|
||||
if (mCreateAction)
|
||||
menu.addAction(mCloneAction);
|
||||
|
||||
if (mModel->getViewing()!=CSMWorld::IdTable::Viewing_None)
|
||||
{
|
||||
int row = selectedRows.begin()->row();
|
||||
|
||||
row = mProxyModel->mapToSource (mProxyModel->index (row, 0)).row();
|
||||
|
||||
CSMWorld::UniversalId id = mModel->view (row).first;
|
||||
|
||||
if (!mDocument.getData().getCells().getRecord (id.getId()).isDeleted())
|
||||
menu.addAction (mViewAction);
|
||||
}
|
||||
}
|
||||
|
||||
if (mCreateAction)
|
||||
|
@ -95,6 +83,28 @@ void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event)
|
|||
}
|
||||
}
|
||||
|
||||
if (selectedRows.size()==1)
|
||||
{
|
||||
if (mModel->getViewing()!=CSMWorld::IdTable::Viewing_None)
|
||||
{
|
||||
int row = selectedRows.begin()->row();
|
||||
|
||||
row = mProxyModel->mapToSource (mProxyModel->index (row, 0)).row();
|
||||
|
||||
CSMWorld::UniversalId id = mModel->view (row).first;
|
||||
|
||||
int index = mDocument.getData().getCells().searchId (id.getId());
|
||||
// index==-1: the ID references a worldspace instead of a cell (ignore for now and go
|
||||
// ahead)
|
||||
|
||||
if (index==-1 || !mDocument.getData().getCells().getRecord (index).isDeleted())
|
||||
menu.addAction (mViewAction);
|
||||
}
|
||||
|
||||
if (mModel->hasPreview())
|
||||
menu.addAction (mPreviewAction);
|
||||
}
|
||||
|
||||
menu.exec (event->globalPos());
|
||||
}
|
||||
|
||||
|
@ -249,6 +259,10 @@ CSVWorld::Table::Table (const CSMWorld::UniversalId& id,
|
|||
connect (mViewAction, SIGNAL (triggered()), this, SLOT (viewRecord()));
|
||||
addAction (mViewAction);
|
||||
|
||||
mPreviewAction = new QAction (tr ("Preview"), this);
|
||||
connect (mPreviewAction, SIGNAL (triggered()), this, SLOT (previewRecord()));
|
||||
addAction (mPreviewAction);
|
||||
|
||||
connect (mProxyModel, SIGNAL (rowsInserted (const QModelIndex&, int, int)),
|
||||
this, SLOT (tableSizeUpdate()));
|
||||
|
||||
|
@ -275,7 +289,7 @@ CSMWorld::UniversalId CSVWorld::Table::getUniversalId (int row) const
|
|||
{
|
||||
return CSMWorld::UniversalId (
|
||||
static_cast<CSMWorld::UniversalId::Type> (mProxyModel->data (mProxyModel->index (row, 2)).toInt()),
|
||||
mProxyModel->data (mProxyModel->index (row, 0)).toString().toStdString());
|
||||
mProxyModel->data (mProxyModel->index (row, 0)).toString().toUtf8().constData());
|
||||
}
|
||||
|
||||
void CSVWorld::Table::revertRecord()
|
||||
|
@ -406,7 +420,7 @@ void CSVWorld::Table::viewRecord()
|
|||
|
||||
if (selectedRows.size()==1)
|
||||
{
|
||||
int row =selectedRows.begin()->row();
|
||||
int row = selectedRows.begin()->row();
|
||||
|
||||
row = mProxyModel->mapToSource (mProxyModel->index (row, 0)).row();
|
||||
|
||||
|
@ -417,6 +431,18 @@ void CSVWorld::Table::viewRecord()
|
|||
}
|
||||
}
|
||||
|
||||
void CSVWorld::Table::previewRecord()
|
||||
{
|
||||
QModelIndexList selectedRows = selectionModel()->selectedRows();
|
||||
|
||||
if (selectedRows.size()==1)
|
||||
{
|
||||
std::string id = getUniversalId (selectedRows.begin()->row()).getId();
|
||||
|
||||
emit editRequest (CSMWorld::UniversalId (CSMWorld::UniversalId::Type_Preview, id) , "");
|
||||
}
|
||||
}
|
||||
|
||||
void CSVWorld::Table::updateEditorSetting (const QString &settingName, const QString &settingValue)
|
||||
{
|
||||
int columns = mModel->columnCount();
|
||||
|
@ -507,28 +533,15 @@ void CSVWorld::Table::mouseMoveEvent (QMouseEvent* event)
|
|||
}
|
||||
|
||||
drag->setMimeData (mime);
|
||||
drag->setPixmap (QString::fromStdString (mime->getIcon()));
|
||||
|
||||
Qt::DropActions action = Qt::IgnoreAction;
|
||||
switch (QApplication::keyboardModifiers())
|
||||
{
|
||||
case Qt::ControlModifier:
|
||||
action = Qt::CopyAction;
|
||||
break;
|
||||
|
||||
case Qt::ShiftModifier:
|
||||
action = Qt::MoveAction;
|
||||
break;
|
||||
}
|
||||
|
||||
drag->exec(action);
|
||||
drag->setPixmap (QString::fromUtf8 (mime->getIcon().c_str()));
|
||||
drag->exec(Qt::CopyAction);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CSVWorld::Table::dragEnterEvent(QDragEnterEvent *event)
|
||||
{
|
||||
event->acceptProposedAction();
|
||||
event->acceptProposedAction();
|
||||
}
|
||||
|
||||
void CSVWorld::Table::dropEvent(QDropEvent *event)
|
||||
|
@ -560,7 +573,7 @@ void CSVWorld::Table::dropEvent(QDropEvent *event)
|
|||
|
||||
void CSVWorld::Table::dragMoveEvent(QDragMoveEvent *event)
|
||||
{
|
||||
event->accept();
|
||||
event->accept();
|
||||
}
|
||||
|
||||
std::vector<std::string> CSVWorld::Table::getColumnsWithDisplay(CSMWorld::ColumnBase::Display display) const
|
||||
|
@ -575,7 +588,7 @@ std::vector<std::string> CSVWorld::Table::getColumnsWithDisplay(CSMWorld::Column
|
|||
|
||||
if (display == columndisplay)
|
||||
{
|
||||
titles.push_back(mModel->headerData (i, Qt::Horizontal).toString().toStdString());
|
||||
titles.push_back(mModel->headerData (i, Qt::Horizontal).toString().toUtf8().constData());
|
||||
}
|
||||
}
|
||||
return titles;
|
||||
|
|
|
@ -44,6 +44,7 @@ namespace CSVWorld
|
|||
QAction *mMoveUpAction;
|
||||
QAction *mMoveDownAction;
|
||||
QAction *mViewAction;
|
||||
QAction *mPreviewAction;
|
||||
CSMWorld::IdTableProxyModel *mProxyModel;
|
||||
CSMWorld::IdTable *mModel;
|
||||
bool mEditLock;
|
||||
|
@ -111,6 +112,8 @@ namespace CSVWorld
|
|||
|
||||
void viewRecord();
|
||||
|
||||
void previewRecord();
|
||||
|
||||
public slots:
|
||||
|
||||
void tableSizeUpdate();
|
||||
|
|
|
@ -4,8 +4,18 @@
|
|||
#include <stdexcept>
|
||||
|
||||
#include <QUndoStack>
|
||||
#include <QMetaProperty>
|
||||
#include <QStyledItemDelegate>
|
||||
#include <QLineEdit>
|
||||
#include <QSpinBox>
|
||||
#include <QDoubleSpinBox>
|
||||
#include <QComboBox>
|
||||
#include <QCheckBox>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QEvent>
|
||||
|
||||
#include "../../model/world/commands.hpp"
|
||||
#include "../../model/world/tablemimedata.hpp"
|
||||
|
||||
CSVWorld::NastyTableModelHack::NastyTableModelHack (QAbstractItemModel& model)
|
||||
: mModel (model)
|
||||
|
@ -117,10 +127,56 @@ void CSVWorld::CommandDelegate::setModelData (QWidget *editor, QAbstractItemMode
|
|||
}
|
||||
|
||||
QWidget *CSVWorld::CommandDelegate::createEditor (QWidget *parent, const QStyleOptionViewItem& option,
|
||||
const QModelIndex& index) const
|
||||
const QModelIndex& index, CSMWorld::ColumnBase::Display display) const
|
||||
{
|
||||
if (!index.data().isValid())
|
||||
return 0;
|
||||
QVariant variant = index.data();
|
||||
if (!variant.isValid())
|
||||
{
|
||||
variant = index.data(Qt::DisplayRole);
|
||||
if (!variant.isValid())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (display != CSMWorld::ColumnBase::Display_None)
|
||||
{
|
||||
if (variant.type() == QVariant::Color)
|
||||
{
|
||||
return new QLineEdit(parent);
|
||||
}
|
||||
if (display == CSMWorld::ColumnBase::Display_Integer)
|
||||
{
|
||||
return new QSpinBox(parent);
|
||||
}
|
||||
if (display == CSMWorld::ColumnBase::Display_Var)
|
||||
{
|
||||
return new QLineEdit(parent);
|
||||
}
|
||||
if (display == CSMWorld::ColumnBase::Display_Float)
|
||||
{
|
||||
return new QDoubleSpinBox(parent);
|
||||
}
|
||||
if (display == CSMWorld::ColumnBase::Display_LongString)
|
||||
{
|
||||
return new QTextEdit(parent);
|
||||
}
|
||||
if (display == CSMWorld::ColumnBase::Display_String ||
|
||||
display == CSMWorld::ColumnBase::Display_Skill ||
|
||||
display == CSMWorld::ColumnBase::Display_Script ||
|
||||
display == CSMWorld::ColumnBase::Display_Race ||
|
||||
display == CSMWorld::ColumnBase::Display_Class ||
|
||||
display == CSMWorld::ColumnBase::Display_Faction ||
|
||||
display == CSMWorld::ColumnBase::Display_Miscellaneous ||
|
||||
display == CSMWorld::ColumnBase::Display_Sound)
|
||||
{
|
||||
return new DropLineEdit(parent);
|
||||
}
|
||||
if (display == CSMWorld::ColumnBase::Display_Boolean)
|
||||
{
|
||||
return new QCheckBox(parent);
|
||||
}
|
||||
}
|
||||
|
||||
return QStyledItemDelegate::createEditor (parent, option, index);
|
||||
}
|
||||
|
@ -140,4 +196,67 @@ bool CSVWorld::CommandDelegate::updateEditorSetting (const QString &settingName,
|
|||
const QString &settingValue)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void CSVWorld::CommandDelegate::setEditorData (QWidget *editor, const QModelIndex& index, bool tryDisplay) const
|
||||
{
|
||||
QVariant v = index.data(Qt::EditRole);
|
||||
if (tryDisplay)
|
||||
{
|
||||
if (!v.isValid())
|
||||
{
|
||||
v = index.data(Qt::DisplayRole);
|
||||
if (!v.isValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
QPlainTextEdit* plainTextEdit = qobject_cast<QPlainTextEdit*>(editor);
|
||||
if(plainTextEdit) //for some reason it is easier to brake the loop here
|
||||
{
|
||||
if(plainTextEdit->toPlainText() == v.toString())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QByteArray n = editor->metaObject()->userProperty().name();
|
||||
|
||||
if (n == "dateTime") {
|
||||
if (editor->inherits("QTimeEdit"))
|
||||
n = "time";
|
||||
else if (editor->inherits("QDateEdit"))
|
||||
n = "date";
|
||||
}
|
||||
|
||||
if (!n.isEmpty()) {
|
||||
if (!v.isValid())
|
||||
v = QVariant(editor->property(n).userType(), (const void *)0);
|
||||
editor->setProperty(n, v);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
CSVWorld::DropLineEdit::DropLineEdit(QWidget* parent) :
|
||||
QLineEdit(parent)
|
||||
{
|
||||
setAcceptDrops(true);
|
||||
}
|
||||
|
||||
void CSVWorld::DropLineEdit::dragEnterEvent(QDragEnterEvent *event)
|
||||
{
|
||||
event->acceptProposedAction();
|
||||
}
|
||||
|
||||
void CSVWorld::DropLineEdit::dragMoveEvent(QDragMoveEvent *event)
|
||||
{
|
||||
event->accept();
|
||||
}
|
||||
|
||||
void CSVWorld::DropLineEdit::dropEvent(QDropEvent *event)
|
||||
{
|
||||
const CSMWorld::TableMimeData* data(dynamic_cast<const CSMWorld::TableMimeData*>(event->mimeData()));
|
||||
emit tableMimeDataDropped(data->getData(), data->getDocumentPtr());
|
||||
//WIP
|
||||
}
|
|
@ -5,11 +5,19 @@
|
|||
|
||||
#include <QAbstractTableModel>
|
||||
#include <QStyledItemDelegate>
|
||||
#include <QLineEdit>
|
||||
|
||||
#include "../../model/world/columnbase.hpp"
|
||||
#include "../../model/doc/document.hpp"
|
||||
|
||||
class QUndoStack;
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class TableMimeData;
|
||||
class UniversalId;
|
||||
}
|
||||
|
||||
namespace CSVWorld
|
||||
{
|
||||
///< \brief Getting the data out of an editor widget
|
||||
|
@ -79,6 +87,24 @@ namespace CSVWorld
|
|||
|
||||
};
|
||||
|
||||
class DropLineEdit : public QLineEdit
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DropLineEdit(QWidget *parent);
|
||||
|
||||
private:
|
||||
void dragEnterEvent(QDragEnterEvent *event);
|
||||
|
||||
void dragMoveEvent(QDragMoveEvent *event);
|
||||
|
||||
void dropEvent(QDropEvent *event);
|
||||
|
||||
signals:
|
||||
void tableMimeDataDropped(const std::vector<CSMWorld::UniversalId>& data, const CSMDoc::Document* document);
|
||||
};
|
||||
|
||||
///< \brief Use commands instead of manipulating the model directly
|
||||
class CommandDelegate : public QStyledItemDelegate
|
||||
{
|
||||
|
@ -101,8 +127,10 @@ namespace CSVWorld
|
|||
virtual void setModelData (QWidget *editor, QAbstractItemModel *model,
|
||||
const QModelIndex& index) const;
|
||||
|
||||
virtual QWidget *createEditor (QWidget *parent, const QStyleOptionViewItem& option,
|
||||
const QModelIndex& index) const;
|
||||
virtual QWidget *createEditor (QWidget *parent,
|
||||
const QStyleOptionViewItem& option,
|
||||
const QModelIndex& index,
|
||||
CSMWorld::ColumnBase::Display display = CSMWorld::ColumnBase::Display_None) const;
|
||||
|
||||
void setEditLock (bool locked);
|
||||
|
||||
|
@ -111,6 +139,9 @@ namespace CSVWorld
|
|||
virtual bool updateEditorSetting (const QString &settingName, const QString &settingValue);
|
||||
///< \return Does column require update?
|
||||
|
||||
virtual void setEditorData (QWidget *editor, const QModelIndex& index, bool tryDisplay = false) const;
|
||||
|
||||
|
||||
private slots:
|
||||
|
||||
virtual void slotUpdateEditorSetting (const QString &settingName, const QString &settingValue) {}
|
||||
|
|
|
@ -33,7 +33,7 @@ add_openmw_dir (mwgui
|
|||
merchantrepair repair soulgemdialog companionwindow bookpage journalviewmodel journalbooks
|
||||
keywordsearch itemmodel containeritemmodel inventoryitemmodel sortfilteritemmodel itemview
|
||||
tradeitemmodel companionitemmodel pickpocketitemmodel fontloader controllers savegamedialog
|
||||
recharge
|
||||
recharge mode videowidget
|
||||
)
|
||||
|
||||
add_openmw_dir (mwdialogue
|
||||
|
@ -44,7 +44,7 @@ add_openmw_dir (mwscript
|
|||
locals scriptmanagerimp compilercontext interpretercontext cellextensions miscextensions
|
||||
guiextensions soundextensions skyextensions statsextensions containerextensions
|
||||
aiextensions controlextensions extensions globalscripts ref dialogueextensions
|
||||
animationextensions transformationextensions consoleextensions userextensions locals
|
||||
animationextensions transformationextensions consoleextensions userextensions
|
||||
)
|
||||
|
||||
add_openmw_dir (mwsound
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
#include <components/compiler/extensions0.hpp>
|
||||
|
||||
#include <components/bsa/bsa_archive.hpp>
|
||||
#include <components/bsa/resources.hpp>
|
||||
#include <components/files/configurationmanager.hpp>
|
||||
#include <components/translation/translation.hpp>
|
||||
#include <components/nif/niffile.hpp>
|
||||
|
@ -192,50 +192,6 @@ OMW::Engine::~Engine()
|
|||
SDL_Quit();
|
||||
}
|
||||
|
||||
// Load BSA files
|
||||
|
||||
void OMW::Engine::loadBSA()
|
||||
{
|
||||
// We use separate resource groups to handle location priority.
|
||||
const Files::PathContainer& dataDirs = mFileCollections.getPaths();
|
||||
|
||||
int i=0;
|
||||
for (Files::PathContainer::const_iterator iter = dataDirs.begin(); iter != dataDirs.end(); ++iter)
|
||||
{
|
||||
// Last data dir has the highest priority
|
||||
std::string groupName = "Data" + Ogre::StringConverter::toString(dataDirs.size()-i, 8, '0');
|
||||
Ogre::ResourceGroupManager::getSingleton ().createResourceGroup (groupName);
|
||||
|
||||
std::string dataDirectory = iter->string();
|
||||
std::cout << "Data dir " << dataDirectory << std::endl;
|
||||
Bsa::addDir(dataDirectory, mFSStrict, groupName);
|
||||
++i;
|
||||
}
|
||||
|
||||
i=0;
|
||||
for (std::vector<std::string>::const_iterator archive = mArchives.begin(); archive != mArchives.end(); ++archive)
|
||||
{
|
||||
if (mFileCollections.doesExist(*archive))
|
||||
{
|
||||
// Last BSA has the highest priority
|
||||
std::string groupName = "DataBSA" + Ogre::StringConverter::toString(mArchives.size()-i, 8, '0');
|
||||
|
||||
Ogre::ResourceGroupManager::getSingleton ().createResourceGroup (groupName);
|
||||
|
||||
const std::string archivePath = mFileCollections.getPath(*archive).string();
|
||||
std::cout << "Adding BSA archive " << archivePath << std::endl;
|
||||
Bsa::addBSA(archivePath, groupName);
|
||||
++i;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::stringstream message;
|
||||
message << "Archive '" << *archive << "' not found";
|
||||
throw std::runtime_error(message.str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add resources directory
|
||||
// \note This function works recursively.
|
||||
|
||||
|
@ -383,10 +339,12 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
|
|||
std::string aa = settings.getString("antialiasing", "Video");
|
||||
windowSettings.fsaa = (aa.substr(0, 4) == "MSAA") ? aa.substr(5, aa.size()-5) : "0";
|
||||
|
||||
SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS,
|
||||
settings.getBool("minimize on focus loss", "Video") ? "1" : "0");
|
||||
|
||||
mOgre->createWindow("OpenMW", windowSettings);
|
||||
|
||||
loadBSA();
|
||||
|
||||
Bsa::registerResources (mFileCollections, mArchives, true, mFSStrict);
|
||||
|
||||
// Create input and UI first to set up a bootstrapping environment for
|
||||
// showing a loading screen and keeping the window responsive while doing so
|
||||
|
@ -401,6 +359,16 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
|
|||
mCfgMgr.getCachePath ().string(), mScriptConsoleMode, mTranslationDataStorage, mEncoding);
|
||||
mEnvironment.setWindowManager (window);
|
||||
|
||||
// Create sound system
|
||||
mEnvironment.setSoundManager (new MWSound::SoundManager(mUseSound));
|
||||
|
||||
if (!mSkipMenu)
|
||||
{
|
||||
std::string logo = mFallbackMap["Movies_Company_Logo"];
|
||||
if (!logo.empty())
|
||||
window->playVideo(logo, 1);
|
||||
}
|
||||
|
||||
// Create the world
|
||||
mEnvironment.setWorld( new MWWorld::World (*mOgre, mFileCollections, mContentFiles,
|
||||
mResDir, mCfgMgr.getCachePath(), mEncoder, mFallbackMap,
|
||||
|
@ -418,9 +386,6 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
|
|||
|
||||
Compiler::registerExtensions (mExtensions);
|
||||
|
||||
// Create sound system
|
||||
mEnvironment.setSoundManager (new MWSound::SoundManager(mUseSound));
|
||||
|
||||
// Create script system
|
||||
mScriptContext = new MWScript::CompilerContext (MWScript::CompilerContext::Type_Full);
|
||||
mScriptContext->setExtensions (&mExtensions);
|
||||
|
@ -479,7 +444,19 @@ void OMW::Engine::go()
|
|||
|
||||
// start in main menu
|
||||
if (!mSkipMenu)
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_MainMenu);
|
||||
try
|
||||
{
|
||||
// Is there an ini setting for this filename or something?
|
||||
MWBase::Environment::get().getSoundManager()->streamMusic("Special/morrowind title.mp3");
|
||||
|
||||
std::string logo = mFallbackMap["Movies_Morrowind_Logo"];
|
||||
if (!logo.empty())
|
||||
MWBase::Environment::get().getWindowManager()->playVideo(logo, true);
|
||||
}
|
||||
catch (...) {}
|
||||
}
|
||||
else
|
||||
MWBase::Environment::get().getStateManager()->newGame (true);
|
||||
|
||||
|
|
|
@ -101,9 +101,6 @@ namespace OMW
|
|||
/// add a .zip resource
|
||||
void addZipResource (const boost::filesystem::path& path);
|
||||
|
||||
/// Load BSA files
|
||||
void loadBSA();
|
||||
|
||||
void executeLocalScripts();
|
||||
|
||||
virtual bool frameRenderingQueued (const Ogre::FrameEvent& evt);
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace MWBase
|
|||
|
||||
virtual ~InputManager() {}
|
||||
|
||||
virtual void update(float dt, bool loading) = 0;
|
||||
virtual void update(float dt, bool disableControls, bool disableEvents=false) = 0;
|
||||
|
||||
virtual void changeInputMode(bool guiMode) = 0;
|
||||
|
||||
|
|
|
@ -156,7 +156,7 @@ namespace MWBase
|
|||
/// paused we may want to do it manually (after equipping permanent enchantment)
|
||||
virtual void updateMagicEffects (const MWWorld::Ptr& ptr) = 0;
|
||||
|
||||
virtual void toggleAI() = 0;
|
||||
virtual bool toggleAI() = 0;
|
||||
virtual bool isAIActive() = 0;
|
||||
|
||||
virtual void getObjectsInRange (const Ogre::Vector3& position, float radius, std::vector<MWWorld::Ptr>& objects) = 0;
|
||||
|
|
|
@ -96,6 +96,10 @@ namespace MWBase
|
|||
*/
|
||||
virtual void update() = 0;
|
||||
|
||||
/// @note This method will block until the video finishes playing
|
||||
/// (and will continually update the window while doing so)
|
||||
virtual void playVideo(const std::string& name, bool allowSkipping) = 0;
|
||||
|
||||
virtual void setNewGame(bool newgame) = 0;
|
||||
|
||||
virtual void pushGuiMode (MWGui::GuiMode mode) = 0;
|
||||
|
|
|
@ -420,8 +420,6 @@ namespace MWBase
|
|||
virtual MWRender::Animation* getAnimation(const MWWorld::Ptr &ptr) = 0;
|
||||
|
||||
/// \todo this does not belong here
|
||||
virtual void playVideo(const std::string& name, bool allowSkipping) = 0;
|
||||
virtual void stopVideo() = 0;
|
||||
virtual void frameStarted (float dt, bool paused) = 0;
|
||||
virtual void screenshot (Ogre::Image& image, int w, int h) = 0;
|
||||
|
||||
|
|
|
@ -28,16 +28,16 @@
|
|||
|
||||
namespace
|
||||
{
|
||||
struct CustomData : public MWWorld::CustomData
|
||||
struct ContainerCustomData : public MWWorld::CustomData
|
||||
{
|
||||
MWWorld::ContainerStore mContainerStore;
|
||||
|
||||
virtual MWWorld::CustomData *clone() const;
|
||||
};
|
||||
|
||||
MWWorld::CustomData *CustomData::clone() const
|
||||
MWWorld::CustomData *ContainerCustomData::clone() const
|
||||
{
|
||||
return new CustomData (*this);
|
||||
return new ContainerCustomData (*this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,7 @@ namespace MWClass
|
|||
{
|
||||
if (!ptr.getRefData().getCustomData())
|
||||
{
|
||||
std::auto_ptr<CustomData> data (new CustomData);
|
||||
std::auto_ptr<ContainerCustomData> data (new ContainerCustomData);
|
||||
|
||||
MWWorld::LiveCellRef<ESM::Container> *ref =
|
||||
ptr.get<ESM::Container>();
|
||||
|
@ -174,7 +174,7 @@ namespace MWClass
|
|||
{
|
||||
ensureCustomData (ptr);
|
||||
|
||||
return dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mContainerStore;
|
||||
return dynamic_cast<ContainerCustomData&> (*ptr.getRefData().getCustomData()).mContainerStore;
|
||||
}
|
||||
|
||||
std::string Container::getScript (const MWWorld::Ptr& ptr) const
|
||||
|
@ -267,7 +267,7 @@ namespace MWClass
|
|||
|
||||
ensureCustomData (ptr);
|
||||
|
||||
dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mContainerStore.
|
||||
dynamic_cast<ContainerCustomData&> (*ptr.getRefData().getCustomData()).mContainerStore.
|
||||
readState (state2.mInventory);
|
||||
}
|
||||
|
||||
|
@ -278,7 +278,7 @@ namespace MWClass
|
|||
|
||||
ensureCustomData (ptr);
|
||||
|
||||
dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mContainerStore.
|
||||
dynamic_cast<ContainerCustomData&> (*ptr.getRefData().getCustomData()).mContainerStore.
|
||||
writeState (state2.mInventory);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
namespace
|
||||
{
|
||||
struct CustomData : public MWWorld::CustomData
|
||||
struct CreatureCustomData : public MWWorld::CustomData
|
||||
{
|
||||
MWMechanics::CreatureStats mCreatureStats;
|
||||
MWWorld::ContainerStore* mContainerStore; // may be InventoryStore for some creatures
|
||||
|
@ -45,13 +45,13 @@ namespace
|
|||
|
||||
virtual MWWorld::CustomData *clone() const;
|
||||
|
||||
CustomData() : mContainerStore(0) {}
|
||||
virtual ~CustomData() { delete mContainerStore; }
|
||||
CreatureCustomData() : mContainerStore(0) {}
|
||||
virtual ~CreatureCustomData() { delete mContainerStore; }
|
||||
};
|
||||
|
||||
MWWorld::CustomData *CustomData::clone() const
|
||||
MWWorld::CustomData *CreatureCustomData::clone() const
|
||||
{
|
||||
CustomData* cloned = new CustomData (*this);
|
||||
CreatureCustomData* cloned = new CreatureCustomData (*this);
|
||||
cloned->mContainerStore = mContainerStore->clone();
|
||||
return cloned;
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ namespace MWClass
|
|||
{
|
||||
if (!ptr.getRefData().getCustomData())
|
||||
{
|
||||
std::auto_ptr<CustomData> data (new CustomData);
|
||||
std::auto_ptr<CreatureCustomData> data (new CreatureCustomData);
|
||||
|
||||
static bool inited = false;
|
||||
if(!inited)
|
||||
|
@ -123,8 +123,13 @@ namespace MWClass
|
|||
else
|
||||
data->mContainerStore = new MWWorld::ContainerStore();
|
||||
|
||||
// Relates to NPC gold reset delay
|
||||
data->mCreatureStats.setTradeTime(MWWorld::TimeStamp(0.0, 0));
|
||||
|
||||
data->mCreatureStats.setGoldPool(ref->mBase->mData.mGold);
|
||||
|
||||
// store
|
||||
ptr.getRefData().setCustomData (data.release());
|
||||
ptr.getRefData().setCustomData(data.release());
|
||||
|
||||
getContainerStore(ptr).fill(ref->mBase->mInventory, getId(ptr), "",
|
||||
MWBase::Environment::get().getWorld()->getStore());
|
||||
|
@ -134,7 +139,7 @@ namespace MWClass
|
|||
getContainerStore(ptr).add(MWWorld::ContainerStore::sGoldId, ref->mBase->mData.mGold, ptr);
|
||||
|
||||
if (ref->mBase->mFlags & ESM::Creature::Weapon)
|
||||
getInventoryStore(ptr).autoEquip(ptr);
|
||||
getInventoryStore(ptr).autoEquip(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -192,7 +197,7 @@ namespace MWClass
|
|||
{
|
||||
ensureCustomData (ptr);
|
||||
|
||||
return dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mCreatureStats;
|
||||
return dynamic_cast<CreatureCustomData&> (*ptr.getRefData().getCustomData()).mCreatureStats;
|
||||
}
|
||||
|
||||
|
||||
|
@ -456,7 +461,7 @@ namespace MWClass
|
|||
{
|
||||
ensureCustomData (ptr);
|
||||
|
||||
return *dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mContainerStore;
|
||||
return *dynamic_cast<CreatureCustomData&> (*ptr.getRefData().getCustomData()).mContainerStore;
|
||||
}
|
||||
|
||||
MWWorld::InventoryStore& Creature::getInventoryStore(const MWWorld::Ptr &ptr) const
|
||||
|
@ -559,7 +564,7 @@ namespace MWClass
|
|||
{
|
||||
ensureCustomData (ptr);
|
||||
|
||||
return dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mMovement;
|
||||
return dynamic_cast<CreatureCustomData&> (*ptr.getRefData().getCustomData()).mMovement;
|
||||
}
|
||||
|
||||
Ogre::Vector3 Creature::getMovementVector (const MWWorld::Ptr& ptr) const
|
||||
|
@ -786,7 +791,7 @@ namespace MWClass
|
|||
|
||||
ensureCustomData (ptr);
|
||||
|
||||
CustomData& customData = dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData());
|
||||
CreatureCustomData& customData = dynamic_cast<CreatureCustomData&> (*ptr.getRefData().getCustomData());
|
||||
|
||||
customData.mContainerStore->readState (state2.mInventory);
|
||||
customData.mCreatureStats.readState (state2.mCreatureStats);
|
||||
|
@ -800,7 +805,7 @@ namespace MWClass
|
|||
|
||||
ensureCustomData (ptr);
|
||||
|
||||
CustomData& customData = dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData());
|
||||
CreatureCustomData& customData = dynamic_cast<CreatureCustomData&> (*ptr.getRefData().getCustomData());
|
||||
|
||||
customData.mContainerStore->writeState (state2.mInventory);
|
||||
customData.mCreatureStats.writeState (state2.mCreatureStats);
|
||||
|
|
|
@ -9,15 +9,15 @@
|
|||
|
||||
namespace
|
||||
{
|
||||
struct CustomData : public MWWorld::CustomData
|
||||
struct CreatureLevListCustomData : public MWWorld::CustomData
|
||||
{
|
||||
// TODO: save the creature we spawned here
|
||||
virtual MWWorld::CustomData *clone() const;
|
||||
};
|
||||
|
||||
MWWorld::CustomData *CustomData::clone() const
|
||||
MWWorld::CustomData *CreatureLevListCustomData::clone() const
|
||||
{
|
||||
return new CustomData (*this);
|
||||
return new CreatureLevListCustomData (*this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,7 @@ namespace MWClass
|
|||
{
|
||||
if (!ptr.getRefData().getCustomData())
|
||||
{
|
||||
std::auto_ptr<CustomData> data (new CustomData);
|
||||
std::auto_ptr<CreatureLevListCustomData> data (new CreatureLevListCustomData);
|
||||
|
||||
MWWorld::LiveCellRef<ESM::CreatureLevList> *ref =
|
||||
ptr.get<ESM::CreatureLevList>();
|
||||
|
|
|
@ -26,12 +26,12 @@
|
|||
|
||||
namespace
|
||||
{
|
||||
struct CustomData : public MWWorld::CustomData
|
||||
struct LightCustomData : public MWWorld::CustomData
|
||||
{
|
||||
float mTime;
|
||||
///< Time remaining
|
||||
|
||||
CustomData(MWWorld::Ptr ptr)
|
||||
LightCustomData(MWWorld::Ptr ptr)
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::Light> *ref = ptr.get<ESM::Light>();
|
||||
mTime = ref->mBase->mData.mTime;
|
||||
|
@ -40,7 +40,7 @@ namespace
|
|||
|
||||
virtual MWWorld::CustomData *clone() const
|
||||
{
|
||||
return new CustomData (*this);
|
||||
return new LightCustomData (*this);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -210,7 +210,7 @@ namespace MWClass
|
|||
{
|
||||
ensureCustomData(ptr);
|
||||
|
||||
float &timeRemaining = dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mTime;
|
||||
float &timeRemaining = dynamic_cast<LightCustomData&> (*ptr.getRefData().getCustomData()).mTime;
|
||||
timeRemaining = duration;
|
||||
}
|
||||
|
||||
|
@ -218,7 +218,7 @@ namespace MWClass
|
|||
{
|
||||
ensureCustomData(ptr);
|
||||
|
||||
return dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mTime;
|
||||
return dynamic_cast<LightCustomData&> (*ptr.getRefData().getCustomData()).mTime;
|
||||
}
|
||||
|
||||
MWWorld::Ptr
|
||||
|
@ -233,7 +233,7 @@ namespace MWClass
|
|||
void Light::ensureCustomData (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
if (!ptr.getRefData().getCustomData())
|
||||
ptr.getRefData().setCustomData(new CustomData(ptr));
|
||||
ptr.getRefData().setCustomData(new LightCustomData(ptr));
|
||||
}
|
||||
|
||||
bool Light::canSell (const MWWorld::Ptr& item, int npcServices) const
|
||||
|
@ -278,7 +278,7 @@ namespace MWClass
|
|||
|
||||
ensureCustomData (ptr);
|
||||
|
||||
dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mTime = state2.mTime;
|
||||
dynamic_cast<LightCustomData&> (*ptr.getRefData().getCustomData()).mTime = state2.mTime;
|
||||
}
|
||||
|
||||
void Light::writeAdditionalState (const MWWorld::Ptr& ptr, ESM::ObjectState& state)
|
||||
|
@ -288,6 +288,6 @@ namespace MWClass
|
|||
|
||||
ensureCustomData (ptr);
|
||||
|
||||
state2.mTime = dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mTime;
|
||||
state2.mTime = dynamic_cast<LightCustomData&> (*ptr.getRefData().getCustomData()).mTime;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
|
||||
namespace
|
||||
{
|
||||
struct CustomData : public MWWorld::CustomData
|
||||
struct NpcCustomData : public MWWorld::CustomData
|
||||
{
|
||||
MWMechanics::NpcStats mNpcStats;
|
||||
MWMechanics::Movement mMovement;
|
||||
|
@ -48,9 +48,9 @@ namespace
|
|||
virtual MWWorld::CustomData *clone() const;
|
||||
};
|
||||
|
||||
MWWorld::CustomData *CustomData::clone() const
|
||||
MWWorld::CustomData *NpcCustomData::clone() const
|
||||
{
|
||||
return new CustomData (*this);
|
||||
return new NpcCustomData (*this);
|
||||
}
|
||||
|
||||
void autoCalculateAttributes (const ESM::NPC* npc, MWMechanics::CreatureStats& creatureStats)
|
||||
|
@ -262,7 +262,7 @@ namespace MWClass
|
|||
}
|
||||
if (!ptr.getRefData().getCustomData())
|
||||
{
|
||||
std::auto_ptr<CustomData> data(new CustomData);
|
||||
std::auto_ptr<NpcCustomData> data(new NpcCustomData);
|
||||
|
||||
MWWorld::LiveCellRef<ESM::NPC> *ref = ptr.get<ESM::NPC>();
|
||||
|
||||
|
@ -357,6 +357,11 @@ namespace MWClass
|
|||
data->mInventoryStore.fill(ref->mBase->mInventory, getId(ptr), "",
|
||||
MWBase::Environment::get().getWorld()->getStore());
|
||||
|
||||
// Relates to NPC gold reset delay
|
||||
data->mNpcStats.setTradeTime(MWWorld::TimeStamp(0.0, 0));
|
||||
|
||||
data->mNpcStats.setGoldPool(gold);
|
||||
|
||||
// store
|
||||
ptr.getRefData().setCustomData (data.release());
|
||||
|
||||
|
@ -365,6 +370,8 @@ namespace MWClass
|
|||
getContainerStore(ptr).add(MWWorld::ContainerStore::sGoldId, gold, ptr);
|
||||
|
||||
getInventoryStore(ptr).autoEquip(ptr);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -436,14 +443,14 @@ namespace MWClass
|
|||
{
|
||||
ensureCustomData (ptr);
|
||||
|
||||
return dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mNpcStats;
|
||||
return dynamic_cast<NpcCustomData&> (*ptr.getRefData().getCustomData()).mNpcStats;
|
||||
}
|
||||
|
||||
MWMechanics::NpcStats& Npc::getNpcStats (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
ensureCustomData (ptr);
|
||||
|
||||
return dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mNpcStats;
|
||||
return dynamic_cast<NpcCustomData&> (*ptr.getRefData().getCustomData()).mNpcStats;
|
||||
}
|
||||
|
||||
|
||||
|
@ -819,7 +826,7 @@ namespace MWClass
|
|||
{
|
||||
ensureCustomData (ptr);
|
||||
|
||||
return dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mInventoryStore;
|
||||
return dynamic_cast<NpcCustomData&> (*ptr.getRefData().getCustomData()).mInventoryStore;
|
||||
}
|
||||
|
||||
MWWorld::InventoryStore& Npc::getInventoryStore (const MWWorld::Ptr& ptr)
|
||||
|
@ -827,7 +834,7 @@ namespace MWClass
|
|||
{
|
||||
ensureCustomData (ptr);
|
||||
|
||||
return dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mInventoryStore;
|
||||
return dynamic_cast<NpcCustomData&> (*ptr.getRefData().getCustomData()).mInventoryStore;
|
||||
}
|
||||
|
||||
std::string Npc::getScript (const MWWorld::Ptr& ptr) const
|
||||
|
@ -841,7 +848,7 @@ namespace MWClass
|
|||
float Npc::getSpeed(const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
const MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||
const CustomData *npcdata = static_cast<const CustomData*>(ptr.getRefData().getCustomData());
|
||||
const NpcCustomData *npcdata = static_cast<const NpcCustomData*>(ptr.getRefData().getCustomData());
|
||||
const MWMechanics::MagicEffects &mageffects = npcdata->mNpcStats.getMagicEffects();
|
||||
|
||||
const float normalizedEncumbrance = Npc::getEncumbrance(ptr) / Npc::getCapacity(ptr);
|
||||
|
@ -896,7 +903,7 @@ namespace MWClass
|
|||
|
||||
float Npc::getJump(const MWWorld::Ptr &ptr) const
|
||||
{
|
||||
const CustomData *npcdata = static_cast<const CustomData*>(ptr.getRefData().getCustomData());
|
||||
const NpcCustomData *npcdata = static_cast<const NpcCustomData*>(ptr.getRefData().getCustomData());
|
||||
const MWMechanics::MagicEffects &mageffects = npcdata->mNpcStats.getMagicEffects();
|
||||
const float encumbranceTerm = fJumpEncumbranceBase->getFloat() +
|
||||
fJumpEncumbranceMultiplier->getFloat() *
|
||||
|
@ -935,7 +942,7 @@ namespace MWClass
|
|||
if (fallHeight >= fallDistanceMin)
|
||||
{
|
||||
const float acrobaticsSkill = MWWorld::Class::get(ptr).getNpcStats (ptr).getSkill(ESM::Skill::Acrobatics).getModified();
|
||||
const CustomData *npcdata = static_cast<const CustomData*>(ptr.getRefData().getCustomData());
|
||||
const NpcCustomData *npcdata = static_cast<const NpcCustomData*>(ptr.getRefData().getCustomData());
|
||||
const float jumpSpellBonus = npcdata->mNpcStats.getMagicEffects().get(ESM::MagicEffect::Jump).mMagnitude;
|
||||
const float fallAcroBase = gmst.find("fFallAcroBase")->getFloat();
|
||||
const float fallAcroMult = gmst.find("fFallAcroMult")->getFloat();
|
||||
|
@ -960,7 +967,7 @@ namespace MWClass
|
|||
{
|
||||
ensureCustomData (ptr);
|
||||
|
||||
return dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mMovement;
|
||||
return dynamic_cast<NpcCustomData&> (*ptr.getRefData().getCustomData()).mMovement;
|
||||
}
|
||||
|
||||
Ogre::Vector3 Npc::getMovementVector (const MWWorld::Ptr& ptr) const
|
||||
|
@ -1266,7 +1273,7 @@ namespace MWClass
|
|||
|
||||
ensureCustomData (ptr);
|
||||
|
||||
CustomData& customData = dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData());
|
||||
NpcCustomData& customData = dynamic_cast<NpcCustomData&> (*ptr.getRefData().getCustomData());
|
||||
|
||||
customData.mInventoryStore.readState (state2.mInventory);
|
||||
customData.mNpcStats.readState (state2.mNpcStats);
|
||||
|
@ -1280,7 +1287,7 @@ namespace MWClass
|
|||
|
||||
ensureCustomData (ptr);
|
||||
|
||||
CustomData& customData = dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData());
|
||||
NpcCustomData& customData = dynamic_cast<NpcCustomData&> (*ptr.getRefData().getCustomData());
|
||||
|
||||
customData.mInventoryStore.writeState (state2.mInventory);
|
||||
customData.mNpcStats.writeState (state2.mNpcStats);
|
||||
|
|
|
@ -26,16 +26,6 @@ namespace
|
|||
return path;
|
||||
}
|
||||
|
||||
std::string getCountString(const int count)
|
||||
{
|
||||
if (count == 1)
|
||||
return "";
|
||||
if (count > 9999)
|
||||
return boost::lexical_cast<std::string>(int(count/1000.f)) + "k";
|
||||
else
|
||||
return boost::lexical_cast<std::string>(count);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace MWGui
|
||||
|
@ -226,7 +216,7 @@ namespace MWGui
|
|||
text->setNeedMouseFocus(false);
|
||||
text->setTextShadow(true);
|
||||
text->setTextShadowColour(MyGUI::Colour(0,0,0));
|
||||
text->setCaption(getCountString(ingredient->getUserData<MWWorld::Ptr>()->getRefData().getCount()));
|
||||
text->setCaption(ItemView::getCountString(ingredient->getUserData<MWWorld::Ptr>()->getRefData().getCount()));
|
||||
}
|
||||
|
||||
mItemView->update();
|
||||
|
|
|
@ -23,19 +23,6 @@
|
|||
#include "sortfilteritemmodel.hpp"
|
||||
#include "pickpocketitemmodel.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
std::string getCountString(const int count)
|
||||
{
|
||||
if (count == 1)
|
||||
return "";
|
||||
if (count > 9999)
|
||||
return boost::lexical_cast<std::string>(int(count/1000.f)) + "k";
|
||||
else
|
||||
return boost::lexical_cast<std::string>(count);
|
||||
}
|
||||
}
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
|
@ -79,7 +66,7 @@ namespace MWGui
|
|||
text->setNeedMouseFocus(false);
|
||||
text->setTextShadow(true);
|
||||
text->setTextShadowColour(MyGUI::Colour(0,0,0));
|
||||
text->setCaption(getCountString(count));
|
||||
text->setCaption(ItemView::getCountString(count));
|
||||
|
||||
sourceView->update();
|
||||
|
||||
|
|
|
@ -23,18 +23,7 @@
|
|||
#include "travelwindow.hpp"
|
||||
#include "bookpage.hpp"
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
MWGui::BookTypesetter::Utf8Span to_utf8_span (char const * text)
|
||||
{
|
||||
typedef MWGui::BookTypesetter::Utf8Point point;
|
||||
|
||||
point begin = reinterpret_cast <point> (text);
|
||||
|
||||
return MWGui::BookTypesetter::Utf8Span (begin, begin + strlen (text));
|
||||
}
|
||||
}
|
||||
#include "journalbooks.hpp" // to_utf8_span
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
#ifndef OPENMW_GAME_MWGUI_HUD_H
|
||||
#define OPENMW_GAME_MWGUI_HUD_H
|
||||
|
||||
#include "mapwindow.hpp"
|
||||
|
||||
#include "../mwmechanics/stat.hpp"
|
||||
|
@ -117,3 +120,5 @@ namespace MWGui
|
|||
void updatePositions();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -162,6 +162,7 @@ namespace MWGui
|
|||
}
|
||||
|
||||
const ItemStack& item = mTradeModel->getItem(index);
|
||||
std::string sound = MWWorld::Class::get(item.mBase).getDownSoundId(item.mBase);
|
||||
|
||||
MWWorld::Ptr object = item.mBase;
|
||||
int count = item.mCount;
|
||||
|
@ -170,6 +171,7 @@ namespace MWGui
|
|||
if (item.mBase.getCellRef().mRefID.size() > 6
|
||||
&& item.mBase.getCellRef().mRefID.substr(0,6) == "bound_")
|
||||
{
|
||||
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
|
||||
MWBase::Environment::get().getWindowManager()->messageBox("#{sBarterDialog12}");
|
||||
return;
|
||||
}
|
||||
|
@ -213,6 +215,7 @@ namespace MWGui
|
|||
int services = MWBase::Environment::get().getWindowManager()->getTradeWindow()->getMerchantServices();
|
||||
if (!MWWorld::Class::get(object).canSell(object, services))
|
||||
{
|
||||
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
|
||||
MWBase::Environment::get().getWindowManager()->
|
||||
messageBox("#{sBarterDialog4}");
|
||||
return;
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
#ifndef OPENMW_GAME_MWGUI_ITEMSELECTION_H
|
||||
#define OPENMW_GAME_MWGUI_ITEMSELECTION_H
|
||||
|
||||
#include "container.hpp"
|
||||
|
||||
namespace MWGui
|
||||
|
@ -32,3 +35,5 @@ namespace MWGui
|
|||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -13,23 +13,19 @@
|
|||
|
||||
#include "itemmodel.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
std::string getCountString(const int count)
|
||||
{
|
||||
if (count == 1)
|
||||
return "";
|
||||
if (count > 9999)
|
||||
return boost::lexical_cast<std::string>(int(count/1000.f)) + "k";
|
||||
else
|
||||
return boost::lexical_cast<std::string>(count);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
std::string ItemView::getCountString(int count)
|
||||
{
|
||||
if (count == 1)
|
||||
return "";
|
||||
if (count > 9999)
|
||||
return boost::lexical_cast<std::string>(int(count/1000.f)) + "k";
|
||||
else
|
||||
return boost::lexical_cast<std::string>(count);
|
||||
}
|
||||
|
||||
ItemView::ItemView()
|
||||
: mModel(NULL)
|
||||
, mScrollView(NULL)
|
||||
|
|
|
@ -30,6 +30,8 @@ namespace MWGui
|
|||
|
||||
void update();
|
||||
|
||||
static std::string getCountString(int count);
|
||||
|
||||
private:
|
||||
virtual void initialiseOverride();
|
||||
|
||||
|
|
|
@ -2,15 +2,6 @@
|
|||
|
||||
namespace
|
||||
{
|
||||
MWGui::BookTypesetter::Utf8Span to_utf8_span (char const * text)
|
||||
{
|
||||
typedef MWGui::BookTypesetter::Utf8Point point;
|
||||
|
||||
point begin = reinterpret_cast <point> (text);
|
||||
|
||||
return MWGui::BookTypesetter::Utf8Span (begin, begin + strlen (text));
|
||||
}
|
||||
|
||||
const MyGUI::Colour linkHot (0.40f, 0.40f, 0.80f);
|
||||
const MyGUI::Colour linkNormal (0.20f, 0.20f, 0.60f);
|
||||
const MyGUI::Colour linkActive (0.50f, 0.50f, 1.00f);
|
||||
|
@ -178,6 +169,15 @@ namespace
|
|||
namespace MWGui
|
||||
{
|
||||
|
||||
MWGui::BookTypesetter::Utf8Span to_utf8_span (char const * text)
|
||||
{
|
||||
typedef MWGui::BookTypesetter::Utf8Point point;
|
||||
|
||||
point begin = reinterpret_cast <point> (text);
|
||||
|
||||
return MWGui::BookTypesetter::Utf8Span (begin, begin + strlen (text));
|
||||
}
|
||||
|
||||
typedef TypesetBook::Ptr book;
|
||||
|
||||
JournalBooks::JournalBooks (JournalViewModel::Ptr model) :
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
namespace MWGui
|
||||
{
|
||||
MWGui::BookTypesetter::Utf8Span to_utf8_span (char const * text);
|
||||
|
||||
struct JournalBooks
|
||||
{
|
||||
typedef TypesetBook::Ptr Book;
|
||||
|
|
|
@ -226,7 +226,7 @@ namespace MWGui
|
|||
}
|
||||
mSceneMgr->setSpecialCaseRenderQueueMode(Ogre::SceneManager::SCRQM_EXCLUDE);
|
||||
|
||||
MWBase::Environment::get().getInputManager()->update(0, true);
|
||||
MWBase::Environment::get().getInputManager()->update(0, true, true);
|
||||
|
||||
// First, swap buffers from last draw, then, queue an update of the
|
||||
// window contents, but don't swap buffers (which would have
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "../mwstate/character.hpp"
|
||||
|
||||
#include "savegamedialog.hpp"
|
||||
#include "confirmationdialog.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
@ -21,12 +22,13 @@ namespace MWGui
|
|||
: OEngine::GUI::Layout("openmw_mainmenu.layout")
|
||||
, mButtonBox(0), mWidth (w), mHeight (h)
|
||||
, mSaveGameDialog(NULL)
|
||||
, mBackground(NULL)
|
||||
{
|
||||
getWidget(mVersionText, "VersionText");
|
||||
std::stringstream sstream;
|
||||
sstream << "OpenMW version: " << OPENMW_VERSION;
|
||||
|
||||
// adding info about git hash if availible
|
||||
// adding info about git hash if available
|
||||
std::string rev = OPENMW_VERSION_COMMITHASH;
|
||||
std::string tag = OPENMW_VERSION_TAGHASH;
|
||||
if (!rev.empty() && !tag.empty())
|
||||
|
@ -58,10 +60,24 @@ namespace MWGui
|
|||
{
|
||||
if (visible)
|
||||
updateMenu();
|
||||
else
|
||||
showBackground(
|
||||
MWBase::Environment::get().getWindowManager()->containsMode(MWGui::GM_MainMenu) &&
|
||||
MWBase::Environment::get().getStateManager()->getState() == MWBase::StateManager::State_NoGame);
|
||||
|
||||
OEngine::GUI::Layout::setVisible (visible);
|
||||
}
|
||||
|
||||
void MainMenu::onNewGameConfirmed()
|
||||
{
|
||||
MWBase::Environment::get().getStateManager()->newGame();
|
||||
}
|
||||
|
||||
void MainMenu::onExitConfirmed()
|
||||
{
|
||||
MWBase::Environment::get().getStateManager()->requestQuit();
|
||||
}
|
||||
|
||||
void MainMenu::onButtonClicked(MyGUI::Widget *sender)
|
||||
{
|
||||
std::string name = *sender->getUserData<std::string>();
|
||||
|
@ -73,11 +89,33 @@ namespace MWGui
|
|||
}
|
||||
else if (name == "options")
|
||||
MWBase::Environment::get().getWindowManager ()->pushGuiMode (GM_Settings);
|
||||
else if (name == "credits")
|
||||
MWBase::Environment::get().getWindowManager()->playVideo("mw_credits.bik", true);
|
||||
else if (name == "exitgame")
|
||||
MWBase::Environment::get().getStateManager()->requestQuit();
|
||||
{
|
||||
if (MWBase::Environment::get().getStateManager()->getState() == MWBase::StateManager::State_NoGame)
|
||||
onExitConfirmed();
|
||||
else
|
||||
{
|
||||
ConfirmationDialog* dialog = MWBase::Environment::get().getWindowManager()->getConfirmationDialog();
|
||||
dialog->open("#{sMessage2}");
|
||||
dialog->eventOkClicked.clear();
|
||||
dialog->eventOkClicked += MyGUI::newDelegate(this, &MainMenu::onExitConfirmed);
|
||||
dialog->eventCancelClicked.clear();
|
||||
}
|
||||
}
|
||||
else if (name == "newgame")
|
||||
{
|
||||
MWBase::Environment::get().getStateManager()->newGame();
|
||||
if (MWBase::Environment::get().getStateManager()->getState() == MWBase::StateManager::State_NoGame)
|
||||
onNewGameConfirmed();
|
||||
else
|
||||
{
|
||||
ConfirmationDialog* dialog = MWBase::Environment::get().getWindowManager()->getConfirmationDialog();
|
||||
dialog->open("#{sNotifyMessage54}");
|
||||
dialog->eventOkClicked.clear();
|
||||
dialog->eventOkClicked += MyGUI::newDelegate(this, &MainMenu::onNewGameConfirmed);
|
||||
dialog->eventCancelClicked.clear();
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
|
@ -92,11 +130,42 @@ namespace MWGui
|
|||
}
|
||||
}
|
||||
|
||||
void MainMenu::showBackground(bool show)
|
||||
{
|
||||
if (mBackground)
|
||||
{
|
||||
MyGUI::Gui::getInstance().destroyWidget(mBackground);
|
||||
mBackground = NULL;
|
||||
}
|
||||
if (show)
|
||||
{
|
||||
if (!mBackground)
|
||||
{
|
||||
mBackground = MyGUI::Gui::getInstance().createWidgetReal<MyGUI::ImageBox>("ImageBox", 0,0,1,1,
|
||||
MyGUI::Align::Stretch, "Menu");
|
||||
mBackground->setImageTexture("black.png");
|
||||
|
||||
// Use black bars to correct aspect ratio. The video player also does it, so we need to do it
|
||||
// for mw_logo.bik to align correctly with menu_morrowind.dds.
|
||||
MyGUI::IntSize screenSize = MyGUI::RenderManager::getInstance().getViewSize();
|
||||
|
||||
// No way to un-hardcode this right now, menu_morrowind.dds is 1024x512 but was designed for 4:3
|
||||
double imageaspect = 4.0/3.0;
|
||||
|
||||
int leftPadding = std::max(0.0, (screenSize.width - screenSize.height * imageaspect) / 2);
|
||||
int topPadding = std::max(0.0, (screenSize.height - screenSize.width / imageaspect) / 2);
|
||||
|
||||
MyGUI::ImageBox* image = mBackground->createWidget<MyGUI::ImageBox>("ImageBox",
|
||||
leftPadding, topPadding, screenSize.width - leftPadding*2, screenSize.height - topPadding*2, MyGUI::Align::Default);
|
||||
image->setImageTexture("textures\\menu_morrowind.dds");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MainMenu::updateMenu()
|
||||
{
|
||||
setCoord(0,0, mWidth, mHeight);
|
||||
|
||||
|
||||
if (!mButtonBox)
|
||||
mButtonBox = mMainWidget->createWidget<MyGUI::Widget>("", MyGUI::IntCoord(0, 0, 0, 0), MyGUI::Align::Default);
|
||||
|
||||
|
@ -104,6 +173,8 @@ namespace MWGui
|
|||
|
||||
MWBase::StateManager::State state = MWBase::Environment::get().getStateManager()->getState();
|
||||
|
||||
showBackground(state == MWBase::StateManager::State_NoGame);
|
||||
|
||||
std::vector<std::string> buttons;
|
||||
|
||||
if (state==MWBase::StateManager::State_Running)
|
||||
|
@ -120,7 +191,10 @@ namespace MWGui
|
|||
buttons.push_back("savegame");
|
||||
|
||||
buttons.push_back("options");
|
||||
//buttons.push_back("credits");
|
||||
|
||||
if (state==MWBase::StateManager::State_NoGame)
|
||||
buttons.push_back("credits");
|
||||
|
||||
buttons.push_back("exitgame");
|
||||
|
||||
// Create new buttons if needed
|
||||
|
@ -155,12 +229,27 @@ namespace MWGui
|
|||
assert(mButtons.find(*it) != mButtons.end());
|
||||
MWGui::ImageButton* button = mButtons[*it];
|
||||
button->setVisible(true);
|
||||
|
||||
MyGUI::IntSize requested = button->getRequestedSize();
|
||||
button->setCoord((maxwidth-requested.width) / 2, curH, requested.width, requested.height);
|
||||
curH += requested.height;
|
||||
|
||||
// Trim off some of the excessive padding
|
||||
// TODO: perhaps do this within ImageButton?
|
||||
int trim = 8;
|
||||
button->setImageCoord(MyGUI::IntCoord(0, trim, requested.width, requested.height-trim));
|
||||
int height = requested.height-trim*2;
|
||||
button->setImageTile(MyGUI::IntSize(requested.width, height));
|
||||
button->setCoord((maxwidth-requested.width) / 2, curH, requested.width, height);
|
||||
curH += height;
|
||||
}
|
||||
|
||||
mButtonBox->setCoord (mWidth/2 - maxwidth/2, mHeight/2 - curH/2, maxwidth, curH);
|
||||
if (state == MWBase::StateManager::State_NoGame)
|
||||
{
|
||||
// Align with the background image
|
||||
int bottomPadding=48;
|
||||
mButtonBox->setCoord (mWidth/2 - maxwidth/2, mHeight - curH - bottomPadding, maxwidth, curH);
|
||||
}
|
||||
else
|
||||
mButtonBox->setCoord (mWidth/2 - maxwidth/2, mHeight/2 - curH/2, maxwidth, curH);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
#ifndef OPENMW_GAME_MWGUI_MAINMENU_H
|
||||
#define OPENMW_GAME_MWGUI_MAINMENU_H
|
||||
|
||||
#include <openengine/gui/layout.hpp>
|
||||
|
||||
#include "imagebutton.hpp"
|
||||
|
@ -26,9 +29,15 @@ namespace MWGui
|
|||
MyGUI::Widget* mButtonBox;
|
||||
MyGUI::TextBox* mVersionText;
|
||||
|
||||
MyGUI::ImageBox* mBackground;
|
||||
|
||||
std::map<std::string, MWGui::ImageButton*> mButtons;
|
||||
|
||||
void onButtonClicked (MyGUI::Widget* sender);
|
||||
void onNewGameConfirmed();
|
||||
void onExitConfirmed();
|
||||
|
||||
void showBackground(bool show);
|
||||
|
||||
void updateMenu();
|
||||
|
||||
|
@ -36,3 +45,5 @@ namespace MWGui
|
|||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -47,9 +47,7 @@ namespace MWGui
|
|||
GM_Loading,
|
||||
GM_LoadingWallpaper,
|
||||
|
||||
GM_QuickKeysMenu,
|
||||
|
||||
GM_Video
|
||||
GM_QuickKeysMenu
|
||||
};
|
||||
|
||||
// Windows shown in inventory mode
|
||||
|
|
|
@ -19,28 +19,8 @@
|
|||
#include "windowmanagerimp.hpp"
|
||||
#include "itemselection.hpp"
|
||||
|
||||
#include "spellwindow.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
bool sortItems(const MWWorld::Ptr& left, const MWWorld::Ptr& right)
|
||||
{
|
||||
int cmp = left.getClass().getName(left).compare(
|
||||
right.getClass().getName(right));
|
||||
return cmp < 0;
|
||||
}
|
||||
|
||||
bool sortSpells(const std::string& left, const std::string& right)
|
||||
{
|
||||
const MWWorld::Store<ESM::Spell> &spells =
|
||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>();
|
||||
|
||||
const ESM::Spell* a = spells.find(left);
|
||||
const ESM::Spell* b = spells.find(right);
|
||||
|
||||
int cmp = a->mName.compare(b->mName);
|
||||
return cmp < 0;
|
||||
}
|
||||
}
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
|
|
@ -86,7 +86,21 @@ namespace MWGui
|
|||
{
|
||||
std::stringstream title;
|
||||
title << it->getSignature().mPlayerName;
|
||||
title << " (Level " << it->getSignature().mPlayerLevel << " " << it->getSignature().mPlayerClass << ")";
|
||||
|
||||
// For a custom class, we will not find it in the store (unless we loaded the savegame first).
|
||||
// Fall back to name stored in savegame header in that case.
|
||||
std::string className;
|
||||
if (it->getSignature().mPlayerClassId.empty())
|
||||
className = it->getSignature().mPlayerClassName;
|
||||
else
|
||||
{
|
||||
// Find the localised name for this class from the store
|
||||
const ESM::Class* class_ = MWBase::Environment::get().getWorld()->getStore().get<ESM::Class>().find(
|
||||
it->getSignature().mPlayerClassId);
|
||||
className = class_->mName;
|
||||
}
|
||||
|
||||
title << " (Level " << it->getSignature().mPlayerLevel << " " << className << ")";
|
||||
|
||||
mCharacterSelection->addItem (title.str());
|
||||
|
||||
|
@ -169,7 +183,10 @@ namespace MWGui
|
|||
else
|
||||
{
|
||||
if (mCurrentCharacter && slot)
|
||||
{
|
||||
MWBase::Environment::get().getStateManager()->loadGame (mCurrentCharacter, slot);
|
||||
MWBase::Environment::get().getWindowManager()->removeGuiMode (MWGui::GM_MainMenu);
|
||||
}
|
||||
}
|
||||
|
||||
setVisible(false);
|
||||
|
@ -241,7 +258,13 @@ namespace MWGui
|
|||
struct tm* timeinfo;
|
||||
timeinfo = localtime(&time);
|
||||
|
||||
text << asctime(timeinfo) << "\n";
|
||||
// Use system/environment locale settings for datetime formatting
|
||||
std::setlocale(LC_TIME, "");
|
||||
|
||||
const int size=1024;
|
||||
char buffer[size];
|
||||
if (std::strftime(buffer, size, "%x %X", timeinfo) > 0)
|
||||
text << buffer << "\n";
|
||||
text << "Level " << slot->mProfile.mPlayerLevel << "\n";
|
||||
text << slot->mProfile.mPlayerCell << "\n";
|
||||
// text << "Time played: " << slot->mProfile.mTimePlayed << "\n";
|
||||
|
|
|
@ -83,91 +83,116 @@ namespace
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* checkButtonType = "CheckButton";
|
||||
const char* sliderType = "Slider";
|
||||
|
||||
std::string getSettingType(MyGUI::Widget* widget)
|
||||
{
|
||||
return widget->getUserString("SettingType");
|
||||
}
|
||||
|
||||
std::string getSettingName(MyGUI::Widget* widget)
|
||||
{
|
||||
return widget->getUserString("SettingName");
|
||||
}
|
||||
|
||||
std::string getSettingCategory(MyGUI::Widget* widget)
|
||||
{
|
||||
return widget->getUserString("SettingCategory");
|
||||
}
|
||||
|
||||
std::string getSettingValueType(MyGUI::Widget* widget)
|
||||
{
|
||||
return widget->getUserString("SettingValueType");
|
||||
}
|
||||
|
||||
void getSettingMinMax(MyGUI::Widget* widget, float& min, float& max)
|
||||
{
|
||||
const char* settingMin = "SettingMin";
|
||||
const char* settingMax = "SettingMax";
|
||||
min = 0.f;
|
||||
max = 1.f;
|
||||
if (!widget->getUserString(settingMin).empty())
|
||||
min = boost::lexical_cast<float>(widget->getUserString(settingMin));
|
||||
if (!widget->getUserString(settingMax).empty())
|
||||
max = boost::lexical_cast<float>(widget->getUserString(settingMax));
|
||||
}
|
||||
}
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
void SettingsWindow::configureWidgets(MyGUI::Widget* widget)
|
||||
{
|
||||
MyGUI::EnumeratorWidgetPtr widgets = widget->getEnumerator();
|
||||
while (widgets.next())
|
||||
{
|
||||
MyGUI::Widget* current = widgets.current();
|
||||
|
||||
std::string type = getSettingType(current);
|
||||
if (type == checkButtonType)
|
||||
{
|
||||
std::string initialValue = Settings::Manager::getBool(getSettingName(current),
|
||||
getSettingCategory(current))
|
||||
? "#{sOn}" : "#{sOff}";
|
||||
current->castType<MyGUI::Button>()->setCaptionWithReplacing(initialValue);
|
||||
current->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
|
||||
}
|
||||
if (type == sliderType)
|
||||
{
|
||||
MyGUI::ScrollBar* scroll = current->castType<MyGUI::ScrollBar>();
|
||||
if (getSettingValueType(current) == "Float")
|
||||
{
|
||||
// TODO: ScrollBar isn't meant for this. should probably use a dedicated FloatSlider widget
|
||||
float min,max;
|
||||
getSettingMinMax(scroll, min, max);
|
||||
float value = Settings::Manager::getFloat(getSettingName(current), getSettingCategory(current));
|
||||
value = (value-min)/(max-min);
|
||||
|
||||
scroll->setScrollPosition( value * (scroll->getScrollRange()-1));
|
||||
}
|
||||
else
|
||||
{
|
||||
int value = Settings::Manager::getFloat(getSettingName(current), getSettingCategory(current));
|
||||
scroll->setScrollPosition(value);
|
||||
}
|
||||
scroll->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition);
|
||||
}
|
||||
|
||||
configureWidgets(current);
|
||||
}
|
||||
}
|
||||
|
||||
SettingsWindow::SettingsWindow() :
|
||||
WindowBase("openmw_settings_window.layout")
|
||||
{
|
||||
configureWidgets(mMainWidget);
|
||||
|
||||
getWidget(mOkButton, "OkButton");
|
||||
getWidget(mBestAttackButton, "BestAttackButton");
|
||||
getWidget(mGrabCursorButton, "GrabCursorButton");
|
||||
getWidget(mSubtitlesButton, "SubtitlesButton");
|
||||
getWidget(mCrosshairButton, "CrosshairButton");
|
||||
getWidget(mResolutionList, "ResolutionList");
|
||||
getWidget(mMenuTransparencySlider, "MenuTransparencySlider");
|
||||
getWidget(mToolTipDelaySlider, "ToolTipDelaySlider");
|
||||
getWidget(mViewDistanceSlider, "ViewDistanceSlider");
|
||||
getWidget(mFullscreenButton, "FullscreenButton");
|
||||
getWidget(mVSyncButton, "VSyncButton");
|
||||
getWidget(mFPSButton, "FPSButton");
|
||||
getWidget(mFOVSlider, "FOVSlider");
|
||||
getWidget(mMasterVolumeSlider, "MasterVolume");
|
||||
getWidget(mVoiceVolumeSlider, "VoiceVolume");
|
||||
getWidget(mEffectsVolumeSlider, "EffectsVolume");
|
||||
getWidget(mFootstepsVolumeSlider, "FootstepsVolume");
|
||||
getWidget(mMusicVolumeSlider, "MusicVolume");
|
||||
getWidget(mAnisotropySlider, "AnisotropySlider");
|
||||
getWidget(mTextureFilteringButton, "TextureFilteringButton");
|
||||
getWidget(mAnisotropyLabel, "AnisotropyLabel");
|
||||
getWidget(mAnisotropyBox, "AnisotropyBox");
|
||||
getWidget(mWaterShaderButton, "WaterShaderButton");
|
||||
getWidget(mReflectObjectsButton, "ReflectObjectsButton");
|
||||
getWidget(mReflectActorsButton, "ReflectActorsButton");
|
||||
getWidget(mReflectTerrainButton, "ReflectTerrainButton");
|
||||
getWidget(mShadersButton, "ShadersButton");
|
||||
getWidget(mShaderModeButton, "ShaderModeButton");
|
||||
getWidget(mShadowsEnabledButton, "ShadowsEnabledButton");
|
||||
getWidget(mShadowsLargeDistance, "ShadowsLargeDistance");
|
||||
getWidget(mShadowsTextureSize, "ShadowsTextureSize");
|
||||
getWidget(mActorShadows, "ActorShadows");
|
||||
getWidget(mStaticsShadows, "StaticsShadows");
|
||||
getWidget(mMiscShadows, "MiscShadows");
|
||||
getWidget(mTerrainShadows, "TerrainShadows");
|
||||
getWidget(mControlsBox, "ControlsBox");
|
||||
getWidget(mResetControlsButton, "ResetControlsButton");
|
||||
getWidget(mInvertYButton, "InvertYButton");
|
||||
getWidget(mCameraSensitivitySlider, "CameraSensitivitySlider");
|
||||
getWidget(mRefractionButton, "RefractionButton");
|
||||
|
||||
mSubtitlesButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
|
||||
mCrosshairButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
|
||||
mBestAttackButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
|
||||
mGrabCursorButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
|
||||
mInvertYButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
|
||||
mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onOkButtonClicked);
|
||||
mShadersButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onShadersToggled);
|
||||
mShaderModeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onShaderModeToggled);
|
||||
mFullscreenButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
|
||||
mWaterShaderButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
|
||||
mRefractionButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
|
||||
mReflectObjectsButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
|
||||
mReflectTerrainButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
|
||||
mReflectActorsButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
|
||||
mTextureFilteringButton->eventComboChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onTextureFilteringChanged);
|
||||
mVSyncButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
|
||||
mFPSButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onFpsToggled);
|
||||
mMenuTransparencySlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition);
|
||||
mFOVSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition);
|
||||
mToolTipDelaySlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition);
|
||||
mViewDistanceSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition);
|
||||
mResolutionList->eventListChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onResolutionSelected);
|
||||
mAnisotropySlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition);
|
||||
|
||||
mShadowsEnabledButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
|
||||
mShadowsLargeDistance->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
|
||||
mShadowsTextureSize->eventComboChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onShadowTextureSizeChanged);
|
||||
mActorShadows->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
|
||||
mStaticsShadows->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
|
||||
mMiscShadows->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
|
||||
mTerrainShadows->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
|
||||
|
||||
mMasterVolumeSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition);
|
||||
mVoiceVolumeSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition);
|
||||
mEffectsVolumeSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition);
|
||||
mFootstepsVolumeSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition);
|
||||
mMusicVolumeSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition);
|
||||
|
||||
center();
|
||||
|
||||
|
@ -194,73 +219,25 @@ namespace MWGui
|
|||
mResolutionList->addItem(str);
|
||||
}
|
||||
|
||||
// read settings
|
||||
int menu_transparency = (mMenuTransparencySlider->getScrollRange()-1) * Settings::Manager::getFloat("menu transparency", "GUI");
|
||||
mMenuTransparencySlider->setScrollPosition(menu_transparency);
|
||||
int tooltip_delay = (mToolTipDelaySlider->getScrollRange()-1) * Settings::Manager::getFloat("tooltip delay", "GUI");
|
||||
mToolTipDelaySlider->setScrollPosition(tooltip_delay);
|
||||
|
||||
mSubtitlesButton->setCaptionWithReplacing(Settings::Manager::getBool("subtitles", "GUI") ? "#{sOn}" : "#{sOff}");
|
||||
mCrosshairButton->setCaptionWithReplacing(Settings::Manager::getBool("crosshair", "HUD") ? "#{sOn}" : "#{sOff}");
|
||||
mBestAttackButton->setCaptionWithReplacing(Settings::Manager::getBool("best attack", "Game") ? "#{sOn}" : "#{sOff}");
|
||||
mGrabCursorButton->setCaptionWithReplacing(Settings::Manager::getBool("grab cursor", "Input") ? "#{sOn}" : "#{sOff}");
|
||||
|
||||
float fovVal = (Settings::Manager::getFloat("field of view", "General")-sFovMin)/(sFovMax-sFovMin);
|
||||
mFOVSlider->setScrollPosition(fovVal * (mFOVSlider->getScrollRange()-1));
|
||||
MyGUI::TextBox* fovText;
|
||||
getWidget(fovText, "FovText");
|
||||
fovText->setCaption("Field of View (" + boost::lexical_cast<std::string>(int(Settings::Manager::getFloat("field of view", "General"))) + ")");
|
||||
|
||||
float anisotropyVal = Settings::Manager::getInt("anisotropy", "General") / 16.0;
|
||||
mAnisotropySlider->setScrollPosition(anisotropyVal * (mAnisotropySlider->getScrollRange()-1));
|
||||
std::string tf = Settings::Manager::getString("texture filtering", "General");
|
||||
mTextureFilteringButton->setCaption(textureFilteringToStr(tf));
|
||||
mAnisotropyLabel->setCaption("Anisotropy (" + boost::lexical_cast<std::string>(Settings::Manager::getInt("anisotropy", "General")) + ")");
|
||||
|
||||
float val = (Settings::Manager::getFloat("max viewing distance", "Viewing distance")-sViewDistMin)/(sViewDistMax-sViewDistMin);
|
||||
int viewdist = (mViewDistanceSlider->getScrollRange()-1) * val;
|
||||
mViewDistanceSlider->setScrollPosition(viewdist);
|
||||
|
||||
mMasterVolumeSlider->setScrollPosition(Settings::Manager::getFloat("master volume", "Sound") * (mMasterVolumeSlider->getScrollRange()-1));
|
||||
mMusicVolumeSlider->setScrollPosition(Settings::Manager::getFloat("music volume", "Sound") * (mMusicVolumeSlider->getScrollRange()-1));
|
||||
mEffectsVolumeSlider->setScrollPosition(Settings::Manager::getFloat("sfx volume", "Sound") * (mEffectsVolumeSlider->getScrollRange()-1));
|
||||
mFootstepsVolumeSlider->setScrollPosition(Settings::Manager::getFloat("footsteps volume", "Sound") * (mFootstepsVolumeSlider->getScrollRange()-1));
|
||||
mVoiceVolumeSlider->setScrollPosition(Settings::Manager::getFloat("voice volume", "Sound") * (mVoiceVolumeSlider->getScrollRange()-1));
|
||||
|
||||
mWaterShaderButton->setCaptionWithReplacing(Settings::Manager::getBool("shader", "Water") ? "#{sOn}" : "#{sOff}");
|
||||
mReflectObjectsButton->setCaptionWithReplacing(Settings::Manager::getBool("reflect statics", "Water") ? "#{sOn}" : "#{sOff}");
|
||||
mReflectActorsButton->setCaptionWithReplacing(Settings::Manager::getBool("reflect actors", "Water") ? "#{sOn}" : "#{sOff}");
|
||||
mReflectTerrainButton->setCaptionWithReplacing(Settings::Manager::getBool("reflect terrain", "Water") ? "#{sOn}" : "#{sOff}");
|
||||
|
||||
mShadowsTextureSize->setCaption (Settings::Manager::getString ("texture size", "Shadows"));
|
||||
mShadowsLargeDistance->setCaptionWithReplacing(Settings::Manager::getBool("split", "Shadows") ? "#{sOn}" : "#{sOff}");
|
||||
|
||||
mShadowsEnabledButton->setCaptionWithReplacing(Settings::Manager::getBool("enabled", "Shadows") ? "#{sOn}" : "#{sOff}");
|
||||
mActorShadows->setCaptionWithReplacing(Settings::Manager::getBool("actor shadows", "Shadows") ? "#{sOn}" : "#{sOff}");
|
||||
mStaticsShadows->setCaptionWithReplacing(Settings::Manager::getBool("statics shadows", "Shadows") ? "#{sOn}" : "#{sOff}");
|
||||
mMiscShadows->setCaptionWithReplacing(Settings::Manager::getBool("misc shadows", "Shadows") ? "#{sOn}" : "#{sOff}");
|
||||
mTerrainShadows->setCaptionWithReplacing(Settings::Manager::getBool("terrain shadows", "Shadows") ? "#{sOn}" : "#{sOff}");
|
||||
|
||||
float cameraSens = (Settings::Manager::getFloat("camera sensitivity", "Input")-0.2)/(5.0-0.2);
|
||||
mCameraSensitivitySlider->setScrollPosition (cameraSens * (mCameraSensitivitySlider->getScrollRange()-1));
|
||||
mCameraSensitivitySlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition);
|
||||
|
||||
mInvertYButton->setCaptionWithReplacing(Settings::Manager::getBool("invert y axis", "Input") ? "#{sOn}" : "#{sOff}");
|
||||
|
||||
mShadersButton->setCaptionWithReplacing (Settings::Manager::getBool("shaders", "Objects") ? "#{sOn}" : "#{sOff}");
|
||||
mShaderModeButton->setCaption (Settings::Manager::getString("shader mode", "General"));
|
||||
|
||||
mRefractionButton->setCaptionWithReplacing (Settings::Manager::getBool("refraction", "Water") ? "#{sOn}" : "#{sOff}");
|
||||
|
||||
if (!Settings::Manager::getBool("shaders", "Objects"))
|
||||
{
|
||||
mRefractionButton->setEnabled(false);
|
||||
mShadowsEnabledButton->setEnabled(false);
|
||||
}
|
||||
|
||||
mFullscreenButton->setCaptionWithReplacing(Settings::Manager::getBool("fullscreen", "Video") ? "#{sOn}" : "#{sOff}");
|
||||
mVSyncButton->setCaptionWithReplacing(Settings::Manager::getBool("vsync", "Video") ? "#{sOn}": "#{sOff}");
|
||||
mFPSButton->setCaptionWithReplacing(fpsLevelToStr(Settings::Manager::getInt("fps", "HUD")));
|
||||
|
||||
MyGUI::TextBox* fovText;
|
||||
getWidget(fovText, "FovText");
|
||||
fovText->setCaption("Field of View (" + boost::lexical_cast<std::string>(int(Settings::Manager::getInt("field of view", "General"))) + ")");
|
||||
}
|
||||
|
||||
void SettingsWindow::onOkButtonClicked(MyGUI::Widget* _sender)
|
||||
|
@ -320,6 +297,39 @@ namespace MWGui
|
|||
newState = true;
|
||||
}
|
||||
|
||||
if (_sender == mVSyncButton)
|
||||
{
|
||||
// Ogre::Window::setVSyncEnabled is bugged in 1.8
|
||||
#if OGRE_VERSION < (1 << 16 | 9 << 8 | 0)
|
||||
MWBase::Environment::get().getWindowManager()->
|
||||
messageBox("VSync will be applied after a restart", std::vector<std::string>());
|
||||
#endif
|
||||
}
|
||||
|
||||
if (_sender == mShadersButton)
|
||||
{
|
||||
if (newState == false)
|
||||
{
|
||||
// refraction needs shaders to display underwater fog
|
||||
mRefractionButton->setCaptionWithReplacing("#{sOff}");
|
||||
mRefractionButton->setEnabled(false);
|
||||
|
||||
Settings::Manager::setBool("refraction", "Water", false);
|
||||
|
||||
// shadows not supported
|
||||
mShadowsEnabledButton->setEnabled(false);
|
||||
mShadowsEnabledButton->setCaptionWithReplacing("#{sOff}");
|
||||
Settings::Manager::setBool("enabled", "Shadows", false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// re-enable
|
||||
mRefractionButton->setEnabled(true);
|
||||
|
||||
mShadowsEnabledButton->setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
if (_sender == mFullscreenButton)
|
||||
{
|
||||
// check if this resolution is supported in fullscreen
|
||||
|
@ -341,64 +351,15 @@ namespace MWGui
|
|||
MWBase::Environment::get().getWindowManager()->
|
||||
messageBox(msg);
|
||||
_sender->castType<MyGUI::Button>()->setCaption(off);
|
||||
}
|
||||
else
|
||||
{
|
||||
Settings::Manager::setBool("fullscreen", "Video", newState);
|
||||
apply();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (_sender == mVSyncButton)
|
||||
|
||||
if (getSettingType(_sender) == checkButtonType)
|
||||
{
|
||||
Settings::Manager::setBool("vsync", "Video", newState);
|
||||
// Ogre::Window::setVSyncEnabled is bugged in 1.8
|
||||
#if OGRE_VERSION < (1 << 16 | 9 << 8 | 0)
|
||||
MWBase::Environment::get().getWindowManager()->
|
||||
messageBox("VSync will be applied after a restart", std::vector<std::string>());
|
||||
#endif
|
||||
apply();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_sender == mVSyncButton)
|
||||
Settings::Manager::setBool("vsync", "Video", newState);
|
||||
if (_sender == mWaterShaderButton)
|
||||
Settings::Manager::setBool("shader", "Water", newState);
|
||||
else if (_sender == mRefractionButton)
|
||||
Settings::Manager::setBool("refraction", "Water", newState);
|
||||
else if (_sender == mReflectObjectsButton)
|
||||
{
|
||||
Settings::Manager::setBool("reflect misc", "Water", newState);
|
||||
Settings::Manager::setBool("reflect statics", "Water", newState);
|
||||
Settings::Manager::setBool("reflect statics small", "Water", newState);
|
||||
}
|
||||
else if (_sender == mReflectActorsButton)
|
||||
Settings::Manager::setBool("reflect actors", "Water", newState);
|
||||
else if (_sender == mReflectTerrainButton)
|
||||
Settings::Manager::setBool("reflect terrain", "Water", newState);
|
||||
else if (_sender == mShadowsEnabledButton)
|
||||
Settings::Manager::setBool("enabled", "Shadows", newState);
|
||||
else if (_sender == mShadowsLargeDistance)
|
||||
Settings::Manager::setBool("split", "Shadows", newState);
|
||||
else if (_sender == mActorShadows)
|
||||
Settings::Manager::setBool("actor shadows", "Shadows", newState);
|
||||
else if (_sender == mStaticsShadows)
|
||||
Settings::Manager::setBool("statics shadows", "Shadows", newState);
|
||||
else if (_sender == mMiscShadows)
|
||||
Settings::Manager::setBool("misc shadows", "Shadows", newState);
|
||||
else if (_sender == mTerrainShadows)
|
||||
Settings::Manager::setBool("terrain shadows", "Shadows", newState);
|
||||
else if (_sender == mInvertYButton)
|
||||
Settings::Manager::setBool("invert y axis", "Input", newState);
|
||||
else if (_sender == mCrosshairButton)
|
||||
Settings::Manager::setBool("crosshair", "HUD", newState);
|
||||
else if (_sender == mSubtitlesButton)
|
||||
Settings::Manager::setBool("subtitles", "GUI", newState);
|
||||
else if (_sender == mBestAttackButton)
|
||||
Settings::Manager::setBool("best attack", "Game", newState);
|
||||
else if (_sender == mGrabCursorButton)
|
||||
Settings::Manager::setBool("grab cursor", "Input", newState);
|
||||
Settings::Manager::setBool(getSettingName(_sender), getSettingCategory(_sender), newState);
|
||||
apply();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -419,50 +380,6 @@ namespace MWGui
|
|||
apply();
|
||||
}
|
||||
|
||||
void SettingsWindow::onShadersToggled(MyGUI::Widget* _sender)
|
||||
{
|
||||
std::string on = MWBase::Environment::get().getWindowManager()->getGameSettingString("sOn", "On");
|
||||
std::string off = MWBase::Environment::get().getWindowManager()->getGameSettingString("sOff", "On");
|
||||
|
||||
std::string val = static_cast<MyGUI::Button*>(_sender)->getCaption();
|
||||
if (val == off)
|
||||
val = on;
|
||||
else
|
||||
val = off;
|
||||
static_cast<MyGUI::Button*>(_sender)->setCaptionWithReplacing (val);
|
||||
|
||||
if (val == off)
|
||||
{
|
||||
Settings::Manager::setBool("shaders", "Objects", false);
|
||||
|
||||
// refraction needs shaders to display underwater fog
|
||||
mRefractionButton->setCaptionWithReplacing("#{sOff}");
|
||||
mRefractionButton->setEnabled(false);
|
||||
|
||||
Settings::Manager::setBool("refraction", "Water", false);
|
||||
Settings::Manager::setBool("underwater effect", "Water", false);
|
||||
|
||||
// shadows not supported
|
||||
mShadowsEnabledButton->setEnabled(false);
|
||||
mShadowsEnabledButton->setCaptionWithReplacing("#{sOff}");
|
||||
Settings::Manager::setBool("enabled", "Shadows", false);
|
||||
}
|
||||
else
|
||||
{
|
||||
Settings::Manager::setBool("shaders", "Objects", true);
|
||||
|
||||
// re-enable
|
||||
mReflectObjectsButton->setEnabled(true);
|
||||
mReflectActorsButton->setEnabled(true);
|
||||
mReflectTerrainButton->setEnabled(true);
|
||||
mRefractionButton->setEnabled(true);
|
||||
|
||||
mShadowsEnabledButton->setEnabled(true);
|
||||
}
|
||||
|
||||
apply();
|
||||
}
|
||||
|
||||
void SettingsWindow::onFpsToggled(MyGUI::Widget* _sender)
|
||||
{
|
||||
int newLevel = (Settings::Manager::getInt("fps", "HUD") + 1) % 3;
|
||||
|
@ -479,39 +396,34 @@ namespace MWGui
|
|||
|
||||
void SettingsWindow::onSliderChangePosition(MyGUI::ScrollBar* scroller, size_t pos)
|
||||
{
|
||||
float val = pos / float(scroller->getScrollRange()-1);
|
||||
if (scroller == mMenuTransparencySlider)
|
||||
Settings::Manager::setFloat("menu transparency", "GUI", val);
|
||||
else if (scroller == mToolTipDelaySlider)
|
||||
Settings::Manager::setFloat("tooltip delay", "GUI", val);
|
||||
else if (scroller == mViewDistanceSlider)
|
||||
Settings::Manager::setFloat("max viewing distance", "Viewing distance", (1-val) * sViewDistMin + val * sViewDistMax);
|
||||
else if (scroller == mFOVSlider)
|
||||
if (getSettingType(scroller) == "Slider")
|
||||
{
|
||||
MyGUI::TextBox* fovText;
|
||||
getWidget(fovText, "FovText");
|
||||
fovText->setCaption("Field of View (" + boost::lexical_cast<std::string>(int((1-val) * sFovMin + val * sFovMax)) + ")");
|
||||
Settings::Manager::setFloat("field of view", "General", (1-val) * sFovMin + val * sFovMax);
|
||||
}
|
||||
else if (scroller == mAnisotropySlider)
|
||||
{
|
||||
mAnisotropyLabel->setCaption("Anisotropy (" + boost::lexical_cast<std::string>(int(val*16)) + ")");
|
||||
Settings::Manager::setInt("anisotropy", "General", val * 16);
|
||||
}
|
||||
else if (scroller == mMasterVolumeSlider)
|
||||
Settings::Manager::setFloat("master volume", "Sound", val);
|
||||
else if (scroller == mVoiceVolumeSlider)
|
||||
Settings::Manager::setFloat("voice volume", "Sound", val);
|
||||
else if (scroller == mEffectsVolumeSlider)
|
||||
Settings::Manager::setFloat("sfx volume", "Sound", val);
|
||||
else if (scroller == mFootstepsVolumeSlider)
|
||||
Settings::Manager::setFloat("footsteps volume", "Sound", val);
|
||||
else if (scroller == mMusicVolumeSlider)
|
||||
Settings::Manager::setFloat("music volume", "Sound", val);
|
||||
else if (scroller == mCameraSensitivitySlider)
|
||||
Settings::Manager::setFloat("camera sensitivity", "Input", (1-val) * 0.2 + val * 5.f);
|
||||
if (getSettingValueType(scroller) == "Float")
|
||||
{
|
||||
float value = pos / float(scroller->getScrollRange()-1);
|
||||
|
||||
apply();
|
||||
float min,max;
|
||||
getSettingMinMax(scroller, min, max);
|
||||
value = min + (max-min) * value;
|
||||
Settings::Manager::setFloat(getSettingName(scroller), getSettingCategory(scroller), value);
|
||||
|
||||
if (scroller == mFOVSlider)
|
||||
{
|
||||
MyGUI::TextBox* fovText;
|
||||
getWidget(fovText, "FovText");
|
||||
fovText->setCaption("Field of View (" + boost::lexical_cast<std::string>(int(value)) + ")");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Settings::Manager::setInt(getSettingName(scroller), getSettingCategory(scroller), pos);
|
||||
if (scroller == mAnisotropySlider)
|
||||
{
|
||||
mAnisotropyLabel->setCaption("Anisotropy (" + boost::lexical_cast<std::string>(pos) + ")");
|
||||
}
|
||||
}
|
||||
apply();
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsWindow::apply()
|
||||
|
|
|
@ -19,61 +19,29 @@ namespace MWGui
|
|||
|
||||
void updateControlsBox();
|
||||
|
||||
private:
|
||||
static int const sFovMin = 30;
|
||||
static int const sFovMax = 140;
|
||||
static int const sViewDistMin = 2000;
|
||||
static int const sViewDistMax = 5600;
|
||||
|
||||
protected:
|
||||
protected:
|
||||
MyGUI::Button* mOkButton;
|
||||
|
||||
MyGUI::ScrollBar* mMenuTransparencySlider;
|
||||
MyGUI::ScrollBar* mToolTipDelaySlider;
|
||||
MyGUI::Button* mSubtitlesButton;
|
||||
MyGUI::Button* mCrosshairButton;
|
||||
MyGUI::Button* mBestAttackButton;
|
||||
MyGUI::Button* mGrabCursorButton;
|
||||
|
||||
// graphics
|
||||
MyGUI::ListBox* mResolutionList;
|
||||
MyGUI::Button* mFullscreenButton;
|
||||
MyGUI::Button* mVSyncButton;
|
||||
MyGUI::Button* mFPSButton;
|
||||
MyGUI::ScrollBar* mViewDistanceSlider;
|
||||
MyGUI::ScrollBar* mFOVSlider;
|
||||
MyGUI::ScrollBar* mAnisotropySlider;
|
||||
MyGUI::ComboBox* mTextureFilteringButton;
|
||||
MyGUI::TextBox* mAnisotropyLabel;
|
||||
MyGUI::Widget* mAnisotropyBox;
|
||||
MyGUI::Button* mWaterShaderButton;
|
||||
MyGUI::Button* mReflectObjectsButton;
|
||||
MyGUI::Button* mReflectActorsButton;
|
||||
MyGUI::Button* mReflectTerrainButton;
|
||||
MyGUI::Button* mShadersButton;
|
||||
MyGUI::Button* mShaderModeButton;
|
||||
MyGUI::Button* mRefractionButton;
|
||||
|
||||
MyGUI::Button* mShadowsEnabledButton;
|
||||
MyGUI::Button* mShadowsLargeDistance;
|
||||
MyGUI::ComboBox* mShadowsTextureSize;
|
||||
MyGUI::Button* mActorShadows;
|
||||
MyGUI::Button* mStaticsShadows;
|
||||
MyGUI::Button* mMiscShadows;
|
||||
MyGUI::Button* mTerrainShadows;
|
||||
|
||||
// audio
|
||||
MyGUI::ScrollBar* mMasterVolumeSlider;
|
||||
MyGUI::ScrollBar* mVoiceVolumeSlider;
|
||||
MyGUI::ScrollBar* mEffectsVolumeSlider;
|
||||
MyGUI::ScrollBar* mFootstepsVolumeSlider;
|
||||
MyGUI::ScrollBar* mMusicVolumeSlider;
|
||||
|
||||
// controls
|
||||
MyGUI::ScrollView* mControlsBox;
|
||||
MyGUI::Button* mResetControlsButton;
|
||||
MyGUI::Button* mInvertYButton;
|
||||
MyGUI::ScrollBar* mCameraSensitivitySlider;
|
||||
|
||||
void onOkButtonClicked(MyGUI::Widget* _sender);
|
||||
void onFpsToggled(MyGUI::Widget* _sender);
|
||||
|
@ -84,7 +52,6 @@ namespace MWGui
|
|||
void onResolutionAccept();
|
||||
void onResolutionCancel();
|
||||
|
||||
void onShadersToggled(MyGUI::Widget* _sender);
|
||||
void onShaderModeToggled(MyGUI::Widget* _sender);
|
||||
void onShadowTextureSizeChanged(MyGUI::ComboBox* _sender, size_t pos);
|
||||
|
||||
|
@ -94,6 +61,8 @@ namespace MWGui
|
|||
void onResetDefaultBindingsAccept ();
|
||||
|
||||
void apply();
|
||||
|
||||
void configureWidgets(MyGUI::Widget* widget);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -18,8 +18,16 @@
|
|||
#include "inventorywindow.hpp"
|
||||
#include "confirmationdialog.hpp"
|
||||
|
||||
namespace
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
bool sortItems(const MWWorld::Ptr& left, const MWWorld::Ptr& right)
|
||||
{
|
||||
int cmp = left.getClass().getName(left).compare(
|
||||
right.getClass().getName(right));
|
||||
return cmp < 0;
|
||||
}
|
||||
|
||||
bool sortSpells(const std::string& left, const std::string& right)
|
||||
{
|
||||
const MWWorld::Store<ESM::Spell> &spells =
|
||||
|
@ -32,16 +40,6 @@ namespace
|
|||
return cmp < 0;
|
||||
}
|
||||
|
||||
bool sortItems(const MWWorld::Ptr& left, const MWWorld::Ptr& right)
|
||||
{
|
||||
int cmp = MWWorld::Class::get(left).getName(left).compare(
|
||||
MWWorld::Class::get(right).getName(right));
|
||||
return cmp < 0;
|
||||
}
|
||||
}
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
SpellWindow::SpellWindow(DragAndDrop* drag)
|
||||
: WindowPinnableBase("openmw_spell_window.layout")
|
||||
, NoDrop(drag, mMainWidget)
|
||||
|
|
|
@ -2,11 +2,16 @@
|
|||
#define MWGUI_SPELLWINDOW_H
|
||||
|
||||
#include "windowpinnablebase.hpp"
|
||||
#include "../mwworld/ptr.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
class SpellIcons;
|
||||
|
||||
bool sortItems(const MWWorld::Ptr& left, const MWWorld::Ptr& right);
|
||||
|
||||
bool sortSpells(const std::string& left, const std::string& right);
|
||||
|
||||
class SpellWindow : public WindowPinnableBase, public NoDrop
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -84,8 +84,11 @@ namespace MWGui
|
|||
mCurrentBalance = 0;
|
||||
mCurrentMerchantOffer = 0;
|
||||
|
||||
checkTradeTime();
|
||||
|
||||
std::vector<MWWorld::Ptr> itemSources;
|
||||
MWBase::Environment::get().getWorld()->getContainersOwnedBy(actor, itemSources);
|
||||
|
||||
// Important: actor goes last, so that items purchased by the merchant go into his inventory
|
||||
itemSources.push_back(actor);
|
||||
std::vector<MWWorld::Ptr> worldItems;
|
||||
|
@ -360,6 +363,8 @@ namespace MWGui
|
|||
addOrRemoveGold(-mCurrentBalance, mPtr);
|
||||
}
|
||||
|
||||
updateTradeTime();
|
||||
|
||||
MWBase::Environment::get().getWindowManager()->getDialogueWindow()->addResponse(
|
||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sBarterDialog5")->getString());
|
||||
|
||||
|
@ -474,4 +479,33 @@ namespace MWGui
|
|||
}
|
||||
return merchantGold;
|
||||
}
|
||||
|
||||
// Relates to NPC gold reset delay
|
||||
void TradeWindow::checkTradeTime()
|
||||
{
|
||||
MWWorld::ContainerStore store = mPtr.getClass().getContainerStore(mPtr);
|
||||
const MWMechanics::CreatureStats &sellerStats = mPtr.getClass().getCreatureStats(mPtr);
|
||||
double delay = boost::lexical_cast<double>(MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fBarterGoldResetDelay")->getInt());
|
||||
|
||||
// if time stamp longer than gold reset delay, reset gold.
|
||||
if (MWBase::Environment::get().getWorld()->getTimeStamp() >= sellerStats.getTradeTime() + delay)
|
||||
{
|
||||
addOrRemoveGold(-store.count(MWWorld::ContainerStore::sGoldId), mPtr);
|
||||
addOrRemoveGold(+sellerStats.getGoldPool(), mPtr);
|
||||
}
|
||||
}
|
||||
|
||||
void TradeWindow::updateTradeTime()
|
||||
{
|
||||
MWWorld::ContainerStore store = mPtr.getClass().getContainerStore(mPtr);
|
||||
MWMechanics::CreatureStats &sellerStats = mPtr.getClass().getCreatureStats(mPtr);
|
||||
double delay = boost::lexical_cast<double>(MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fBarterGoldResetDelay")->getInt());
|
||||
|
||||
// If trade timestamp is within reset delay don't set
|
||||
if ( ! (MWBase::Environment::get().getWorld()->getTimeStamp() >= sellerStats.getTradeTime() &&
|
||||
MWBase::Environment::get().getWorld()->getTimeStamp() < sellerStats.getTradeTime() + delay) )
|
||||
{
|
||||
sellerStats.setTradeTime(MWBase::Environment::get().getWorld()->getTimeStamp());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -100,6 +100,10 @@ namespace MWGui
|
|||
virtual void onReferenceUnavailable();
|
||||
|
||||
int getMerchantGold();
|
||||
|
||||
// Relates to NPC gold reset delay
|
||||
void checkTradeTime();
|
||||
void updateTradeTime();
|
||||
};
|
||||
}
|
||||
|
||||
|
|
45
apps/openmw/mwgui/videowidget.cpp
Normal file
45
apps/openmw/mwgui/videowidget.cpp
Normal file
|
@ -0,0 +1,45 @@
|
|||
#include "videowidget.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
VideoWidget::VideoWidget()
|
||||
: mAllowSkipping(true)
|
||||
{
|
||||
eventKeyButtonPressed += MyGUI::newDelegate(this, &VideoWidget::onKeyPressed);
|
||||
|
||||
setNeedKeyFocus(true);
|
||||
}
|
||||
|
||||
void VideoWidget::playVideo(const std::string &video, bool allowSkipping)
|
||||
{
|
||||
mAllowSkipping = allowSkipping;
|
||||
|
||||
mPlayer.playVideo(video);
|
||||
|
||||
setImageTexture(mPlayer.getTextureName());
|
||||
}
|
||||
|
||||
int VideoWidget::getVideoWidth()
|
||||
{
|
||||
return mPlayer.getVideoWidth();
|
||||
}
|
||||
|
||||
int VideoWidget::getVideoHeight()
|
||||
{
|
||||
return mPlayer.getVideoHeight();
|
||||
}
|
||||
|
||||
void VideoWidget::onKeyPressed(MyGUI::Widget *_sender, MyGUI::KeyCode _key, MyGUI::Char _char)
|
||||
{
|
||||
if (_key == MyGUI::KeyCode::Escape && mAllowSkipping)
|
||||
mPlayer.stopVideo();
|
||||
}
|
||||
|
||||
bool VideoWidget::update()
|
||||
{
|
||||
mPlayer.update();
|
||||
return mPlayer.isPlaying();
|
||||
}
|
||||
|
||||
}
|
39
apps/openmw/mwgui/videowidget.hpp
Normal file
39
apps/openmw/mwgui/videowidget.hpp
Normal file
|
@ -0,0 +1,39 @@
|
|||
#ifndef OPENMW_MWGUI_VIDEOWIDGET_H
|
||||
#define OPENMW_MWGUI_VIDEOWIDGET_H
|
||||
|
||||
#include <MyGUI_ImageBox.h>
|
||||
|
||||
#include "../mwrender/videoplayer.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
||||
/**
|
||||
* Widget that plays a video. Can be skipped by pressing Esc.
|
||||
*/
|
||||
class VideoWidget : public MyGUI::ImageBox
|
||||
{
|
||||
public:
|
||||
MYGUI_RTTI_DERIVED(VideoWidget)
|
||||
|
||||
VideoWidget();
|
||||
|
||||
void playVideo (const std::string& video, bool allowSkipping);
|
||||
|
||||
int getVideoWidth();
|
||||
int getVideoHeight();
|
||||
|
||||
/// @return Is the video still playing?
|
||||
bool update();
|
||||
|
||||
private:
|
||||
bool mAllowSkipping;
|
||||
|
||||
MWRender::VideoPlayer mPlayer;
|
||||
|
||||
void onKeyPressed(MyGUI::Widget *_sender, MyGUI::KeyCode _key, MyGUI::Char _char);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -4,6 +4,7 @@
|
|||
#include <iterator>
|
||||
|
||||
#include <OgreTextureManager.h>
|
||||
#include <OgreRenderWindow.h>
|
||||
|
||||
#include "MyGUI_UString.h"
|
||||
#include "MyGUI_IPointer.h"
|
||||
|
@ -59,6 +60,7 @@
|
|||
#include "bookpage.hpp"
|
||||
#include "itemview.hpp"
|
||||
#include "fontloader.hpp"
|
||||
#include "videowidget.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
@ -104,6 +106,8 @@ namespace MWGui
|
|||
, mRecharge(NULL)
|
||||
, mRepair(NULL)
|
||||
, mCompanionWindow(NULL)
|
||||
, mVideoBackground(NULL)
|
||||
, mVideoWidget(NULL)
|
||||
, mTranslationDataStorage (translationDataStorage)
|
||||
, mCharGen(NULL)
|
||||
, mInputBlocker(NULL)
|
||||
|
@ -155,6 +159,7 @@ namespace MWGui
|
|||
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::ExposedWindow>("Widget");
|
||||
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Widgets::MWScrollView>("Widget");
|
||||
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Widgets::MWScrollBar>("Widget");
|
||||
MyGUI::FactoryManager::getInstance().registerFactory<VideoWidget>("Widget");
|
||||
BookPage::registerMyGUIComponents ();
|
||||
ItemView::registerComponents();
|
||||
|
||||
|
@ -186,6 +191,13 @@ namespace MWGui
|
|||
|
||||
// hide mygui's pointer
|
||||
MyGUI::PointerManager::getInstance().setVisible(false);
|
||||
|
||||
mVideoBackground = MyGUI::Gui::getInstance().createWidgetReal<MyGUI::ImageBox>("ImageBox", 0,0,1,1,
|
||||
MyGUI::Align::Default, "Overlay");
|
||||
mVideoBackground->setImageTexture("black.png");
|
||||
mVideoBackground->setVisible(false);
|
||||
|
||||
mVideoWidget = mVideoBackground->createWidgetReal<VideoWidget>("ImageBox", 0,0,1,1, MyGUI::Align::Default);
|
||||
}
|
||||
|
||||
void WindowManager::initUI()
|
||||
|
@ -391,6 +403,7 @@ namespace MWGui
|
|||
mCompanionWindow->setVisible(false);
|
||||
mInventoryWindow->setTrading(false);
|
||||
mRecharge->setVisible(false);
|
||||
mVideoBackground->setVisible(false);
|
||||
|
||||
mHud->setVisible(mHudEnabled);
|
||||
|
||||
|
@ -539,10 +552,6 @@ namespace MWGui
|
|||
|
||||
setCursorVisible(false);
|
||||
break;
|
||||
case GM_Video:
|
||||
setCursorVisible(false);
|
||||
mHud->setVisible(false);
|
||||
break;
|
||||
default:
|
||||
// Unsupported mode, switch back to game
|
||||
break;
|
||||
|
@ -894,6 +903,7 @@ namespace MWGui
|
|||
|
||||
void WindowManager::windowResized(int x, int y)
|
||||
{
|
||||
sizeVideo(x, y);
|
||||
mGuiManager->windowResized();
|
||||
mLoadingScreen->onResChange (x,y);
|
||||
if (!mHud)
|
||||
|
@ -1401,4 +1411,57 @@ namespace MWGui
|
|||
mMap->readRecord(reader, type);
|
||||
}
|
||||
|
||||
void WindowManager::playVideo(const std::string &name, bool allowSkipping)
|
||||
{
|
||||
mVideoWidget->playVideo("video\\" + name, allowSkipping);
|
||||
|
||||
// Turn off all rendering except for the GUI
|
||||
mRendering->getScene()->clearSpecialCaseRenderQueues();
|
||||
// SCRQM_INCLUDE with RENDER_QUEUE_OVERLAY does not work?
|
||||
for(int i = 0;i < Ogre::RENDER_QUEUE_MAX;++i)
|
||||
{
|
||||
if(i > 0 && i < 96)
|
||||
mRendering->getScene()->addSpecialCaseRenderQueue(i);
|
||||
}
|
||||
mRendering->getScene()->setSpecialCaseRenderQueueMode(Ogre::SceneManager::SCRQM_EXCLUDE);
|
||||
|
||||
MyGUI::IntSize screenSize = MyGUI::RenderManager::getInstance().getViewSize();
|
||||
sizeVideo(screenSize.width, screenSize.height);
|
||||
|
||||
setKeyFocusWidget(mVideoWidget);
|
||||
|
||||
mVideoBackground->setVisible(true);
|
||||
|
||||
bool cursorWasVisible = mCursorVisible;
|
||||
setCursorVisible(false);
|
||||
|
||||
while (mVideoWidget->update())
|
||||
{
|
||||
MWBase::Environment::get().getInputManager()->update(0, true, false);
|
||||
|
||||
mRendering->getWindow()->update();
|
||||
}
|
||||
|
||||
setCursorVisible(cursorWasVisible);
|
||||
|
||||
// Restore normal rendering
|
||||
mRendering->getScene()->clearSpecialCaseRenderQueues();
|
||||
mRendering->getScene()->setSpecialCaseRenderQueueMode(Ogre::SceneManager::SCRQM_EXCLUDE);
|
||||
|
||||
mVideoBackground->setVisible(false);
|
||||
}
|
||||
|
||||
void WindowManager::sizeVideo(int screenWidth, int screenHeight)
|
||||
{
|
||||
// Use black bars to correct aspect ratio
|
||||
mVideoBackground->setSize(screenWidth, screenHeight);
|
||||
|
||||
double imageaspect = static_cast<double>(mVideoWidget->getVideoWidth())/mVideoWidget->getVideoHeight();
|
||||
|
||||
int leftPadding = std::max(0.0, (screenWidth - screenHeight * imageaspect) / 2);
|
||||
int topPadding = std::max(0.0, (screenHeight - screenWidth / imageaspect) / 2);
|
||||
|
||||
mVideoWidget->setCoord(leftPadding, topPadding,
|
||||
screenWidth - leftPadding*2, screenHeight - topPadding*2);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ namespace MyGUI
|
|||
class Widget;
|
||||
class Window;
|
||||
class UString;
|
||||
class ImageBox;
|
||||
}
|
||||
|
||||
namespace Compiler
|
||||
|
@ -80,6 +81,7 @@ namespace MWGui
|
|||
class SoulgemDialog;
|
||||
class Recharge;
|
||||
class CompanionWindow;
|
||||
class VideoWidget;
|
||||
|
||||
class WindowManager : public MWBase::WindowManager
|
||||
{
|
||||
|
@ -98,6 +100,10 @@ namespace MWGui
|
|||
|
||||
virtual Loading::Listener* getLoadingScreen();
|
||||
|
||||
/// @note This method will block until the video finishes playing
|
||||
/// (and will continually update the window while doing so)
|
||||
virtual void playVideo(const std::string& name, bool allowSkipping);
|
||||
|
||||
/**
|
||||
* Should be called each frame to update windows/gui elements.
|
||||
* This could mean updating sizes of gui elements or opening
|
||||
|
@ -332,6 +338,8 @@ namespace MWGui
|
|||
Repair* mRepair;
|
||||
Recharge* mRecharge;
|
||||
CompanionWindow* mCompanionWindow;
|
||||
MyGUI::ImageBox* mVideoBackground;
|
||||
VideoWidget* mVideoWidget;
|
||||
|
||||
Translation::Storage& mTranslationDataStorage;
|
||||
Cursor* mSoftwareCursor;
|
||||
|
@ -390,6 +398,8 @@ namespace MWGui
|
|||
|
||||
void onCursorChange(const std::string& name);
|
||||
void onKeyFocusChanged(MyGUI::Widget* widget);
|
||||
|
||||
void sizeVideo(int screenWidth, int screenHeight);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -96,12 +96,12 @@ namespace MWInput
|
|||
: mOgre(ogre)
|
||||
, mPlayer(NULL)
|
||||
, mEngine(engine)
|
||||
, mMouseLookEnabled(true)
|
||||
, mMouseLookEnabled(false)
|
||||
, mMouseX(ogre.getWindow()->getWidth ()/2.f)
|
||||
, mMouseY(ogre.getWindow()->getHeight ()/2.f)
|
||||
, mMouseWheel(0)
|
||||
, mDragDrop(false)
|
||||
, mGuiCursorEnabled(false)
|
||||
, mGuiCursorEnabled(true)
|
||||
, mUserFile(userFile)
|
||||
, mUserFileExists(userFileExists)
|
||||
, mInvertY (Settings::Manager::getBool("invert y axis", "Input"))
|
||||
|
@ -256,18 +256,21 @@ namespace MWInput
|
|||
}
|
||||
}
|
||||
|
||||
void InputManager::update(float dt, bool loading)
|
||||
void InputManager::update(float dt, bool disableControls, bool disableEvents)
|
||||
{
|
||||
mInputManager->setMouseVisible(MWBase::Environment::get().getWindowManager()->getCursorVisible());
|
||||
|
||||
mInputManager->capture(loading);
|
||||
mInputManager->capture(disableEvents);
|
||||
// inject some fake mouse movement to force updating MyGUI's widget states
|
||||
MyGUI::InputManager::getInstance().injectMouseMove( int(mMouseX), int(mMouseY), mMouseWheel);
|
||||
|
||||
// update values of channels (as a result of pressed keys)
|
||||
if (!loading)
|
||||
if (!disableControls)
|
||||
mInputBinder->update(dt);
|
||||
|
||||
if (disableControls)
|
||||
return;
|
||||
|
||||
bool grab = !MWBase::Environment::get().getWindowManager()->containsMode(MWGui::GM_MainMenu)
|
||||
&& MWBase::Environment::get().getWindowManager()->getMode() != MWGui::GM_Console;
|
||||
|
||||
|
@ -288,9 +291,6 @@ namespace MWInput
|
|||
mInputManager->warpMouse(mMouseX, mMouseY);
|
||||
}
|
||||
|
||||
if (loading)
|
||||
return;
|
||||
|
||||
// Disable movement in Gui mode
|
||||
if (MWBase::Environment::get().getWindowManager()->isGuiMode()
|
||||
|| MWBase::Environment::get().getStateManager()->getState() != MWBase::StateManager::State_Running)
|
||||
|
@ -626,9 +626,7 @@ namespace MWInput
|
|||
if (MyGUI::InputManager::getInstance ().isModalAny())
|
||||
return;
|
||||
|
||||
if (MWBase::Environment::get().getWindowManager()->isGuiMode () && MWBase::Environment::get().getWindowManager()->getMode () == MWGui::GM_Video)
|
||||
MWBase::Environment::get().getWorld ()->stopVideo ();
|
||||
else if (MWBase::Environment::get().getWindowManager()->containsMode(MWGui::GM_MainMenu))
|
||||
if (MWBase::Environment::get().getWindowManager()->containsMode(MWGui::GM_MainMenu))
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->popGuiMode();
|
||||
MWBase::Environment::get().getSoundManager()->resumeSounds (MWBase::SoundManager::Play_TypeSfx);
|
||||
|
|
|
@ -68,7 +68,7 @@ namespace MWInput
|
|||
/// Clear all savegame-specific data
|
||||
virtual void clear();
|
||||
|
||||
virtual void update(float dt, bool loading);
|
||||
virtual void update(float dt, bool disableControls, bool disableEvents=false);
|
||||
|
||||
void setPlayer (MWWorld::Player* player) { mPlayer = player; }
|
||||
|
||||
|
|
|
@ -10,16 +10,6 @@
|
|||
#include "steering.hpp"
|
||||
#include "movement.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
float sgn(float a)
|
||||
{
|
||||
if(a > 0)
|
||||
return 1.0;
|
||||
return -1.0;
|
||||
}
|
||||
}
|
||||
|
||||
MWMechanics::AiActivate::AiActivate(const std::string &objectId)
|
||||
: mObjectId(objectId)
|
||||
{
|
||||
|
@ -38,7 +28,7 @@ bool MWMechanics::AiActivate::execute (const MWWorld::Ptr& actor,float duration)
|
|||
MWWorld::Ptr player = world->getPlayerPtr();
|
||||
if(cell->mData.mX != player.getCell()->getCell()->mData.mX)
|
||||
{
|
||||
int sideX = sgn(cell->mData.mX - player.getCell()->getCell()->mData.mX);
|
||||
int sideX = PathFinder::sgn(cell->mData.mX - player.getCell()->getCell()->mData.mX);
|
||||
//check if actor is near the border of an inactive cell. If so, stop walking.
|
||||
if(sideX * (pos.pos[0] - cell->mData.mX*ESM::Land::REAL_SIZE) >
|
||||
sideX * (ESM::Land::REAL_SIZE/2.0f - 200.0f))
|
||||
|
@ -49,7 +39,7 @@ bool MWMechanics::AiActivate::execute (const MWWorld::Ptr& actor,float duration)
|
|||
}
|
||||
if(cell->mData.mY != player.getCell()->getCell()->mData.mY)
|
||||
{
|
||||
int sideY = sgn(cell->mData.mY - player.getCell()->getCell()->mData.mY);
|
||||
int sideY = PathFinder::sgn(cell->mData.mY - player.getCell()->getCell()->mData.mY);
|
||||
//check if actor is near the border of an inactive cell. If so, stop walking.
|
||||
if(sideY * (pos.pos[1] - cell->mData.mY*ESM::Land::REAL_SIZE) >
|
||||
sideY * (ESM::Land::REAL_SIZE/2.0f - 200.0f))
|
||||
|
|
|
@ -11,16 +11,6 @@
|
|||
#include "steering.hpp"
|
||||
#include "movement.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
float sgn(float a)
|
||||
{
|
||||
if(a > 0)
|
||||
return 1.0;
|
||||
return -1.0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
TODO: Test vanilla behavior on passing x0, y0, and z0 with duration of anything including 0.
|
||||
TODO: Different behavior for AIEscort a d x y z and AIEscortCell a c d x y z.
|
||||
|
@ -91,7 +81,7 @@ namespace MWMechanics
|
|||
|
||||
if(actor.getCell()->getCell()->mData.mX != player.getCell()->getCell()->mData.mX)
|
||||
{
|
||||
int sideX = sgn(actor.getCell()->getCell()->mData.mX - player.getCell()->getCell()->mData.mX);
|
||||
int sideX = PathFinder::sgn(actor.getCell()->getCell()->mData.mX - player.getCell()->getCell()->mData.mX);
|
||||
// Check if actor is near the border of an inactive cell. If so, pause walking.
|
||||
if(sideX * (pos.pos[0] - actor.getCell()->getCell()->mData.mX * ESM::Land::REAL_SIZE) > sideX * (ESM::Land::REAL_SIZE /
|
||||
2.0 - 200))
|
||||
|
@ -102,7 +92,7 @@ namespace MWMechanics
|
|||
}
|
||||
if(actor.getCell()->getCell()->mData.mY != player.getCell()->getCell()->mData.mY)
|
||||
{
|
||||
int sideY = sgn(actor.getCell()->getCell()->mData.mY - player.getCell()->getCell()->mData.mY);
|
||||
int sideY = PathFinder::sgn(actor.getCell()->getCell()->mData.mY - player.getCell()->getCell()->mData.mY);
|
||||
// Check if actor is near the border of an inactive cell. If so, pause walking.
|
||||
if(sideY*(pos.pos[1] - actor.getCell()->getCell()->mData.mY * ESM::Land::REAL_SIZE) > sideY * (ESM::Land::REAL_SIZE /
|
||||
2.0 - 200))
|
||||
|
|
|
@ -9,16 +9,6 @@
|
|||
#include "steering.hpp"
|
||||
#include "movement.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
float sgn(float a)
|
||||
{
|
||||
if(a > 0)
|
||||
return 1.0;
|
||||
return -1.0;
|
||||
}
|
||||
}
|
||||
|
||||
namespace MWMechanics
|
||||
{
|
||||
AiTravel::AiTravel(float x, float y, float z)
|
||||
|
@ -43,7 +33,7 @@ namespace MWMechanics
|
|||
MWWorld::Ptr player = world->getPlayerPtr();
|
||||
if(cell->mData.mX != player.getCell()->getCell()->mData.mX)
|
||||
{
|
||||
int sideX = sgn(cell->mData.mX - player.getCell()->getCell()->mData.mX);
|
||||
int sideX = PathFinder::sgn(cell->mData.mX - player.getCell()->getCell()->mData.mX);
|
||||
//check if actor is near the border of an inactive cell. If so, stop walking.
|
||||
if(sideX * (pos.pos[0] - cell->mData.mX*ESM::Land::REAL_SIZE) >
|
||||
sideX * (ESM::Land::REAL_SIZE/2.0f - 200.0f))
|
||||
|
@ -54,7 +44,7 @@ namespace MWMechanics
|
|||
}
|
||||
if(cell->mData.mY != player.getCell()->getCell()->mData.mY)
|
||||
{
|
||||
int sideY = sgn(cell->mData.mY - player.getCell()->getCell()->mData.mY);
|
||||
int sideY = PathFinder::sgn(cell->mData.mY - player.getCell()->getCell()->mData.mY);
|
||||
//check if actor is near the border of an inactive cell. If so, stop walking.
|
||||
if(sideY * (pos.pos[1] - cell->mData.mY*ESM::Land::REAL_SIZE) >
|
||||
sideY * (ESM::Land::REAL_SIZE/2.0f - 200.0f))
|
||||
|
|
|
@ -15,16 +15,6 @@
|
|||
#include "steering.hpp"
|
||||
#include "movement.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
float sgn(float a)
|
||||
{
|
||||
if(a > 0)
|
||||
return 1.0;
|
||||
return -1.0;
|
||||
}
|
||||
}
|
||||
|
||||
namespace MWMechanics
|
||||
{
|
||||
// NOTE: determined empirically but probably need further tweaking
|
||||
|
|
|
@ -414,6 +414,16 @@ void CharacterController::playRandomDeath(float startpoint)
|
|||
mDeathState = CharState_SwimDeath;
|
||||
mCurrentDeath = "swimdeath";
|
||||
}
|
||||
else if (mHitState == CharState_KnockDown)
|
||||
{
|
||||
mDeathState = CharState_DeathKnockDown;
|
||||
mCurrentDeath = "deathknockdown";
|
||||
}
|
||||
else if (mHitState == CharState_KnockOut)
|
||||
{
|
||||
mDeathState = CharState_DeathKnockOut;
|
||||
mCurrentDeath = "deathknockout";
|
||||
}
|
||||
else
|
||||
{
|
||||
int selected=0;
|
||||
|
@ -1245,12 +1255,8 @@ void CharacterController::update(float duration)
|
|||
else //avoid z-rotating for knockdown
|
||||
world->rotateObject(mPtr, rot.x, rot.y, 0.0f, true);
|
||||
|
||||
// always control actual movement by animation unless this:
|
||||
// FIXME: actor falling/landing should be controlled by physics engine
|
||||
if(mMovementAnimVelocity == 0.0f && (vec.length() > 0.0f || mJumpState != JumpState_None))
|
||||
{
|
||||
if (mMovementAnimVelocity == 0)
|
||||
world->queueMovement(mPtr, vec);
|
||||
}
|
||||
}
|
||||
|
||||
movement = vec;
|
||||
|
@ -1290,7 +1296,7 @@ void CharacterController::update(float duration)
|
|||
}
|
||||
|
||||
// Update movement
|
||||
if(moved.squaredLength() > 1.0f)
|
||||
if(mMovementAnimVelocity > 0)
|
||||
world->queueMovement(mPtr, moved);
|
||||
}
|
||||
mSkipAnim = false;
|
||||
|
|
|
@ -90,6 +90,8 @@ enum CharacterState {
|
|||
CharState_Death4,
|
||||
CharState_Death5,
|
||||
CharState_SwimDeath,
|
||||
CharState_DeathKnockDown,
|
||||
CharState_DeathKnockOut,
|
||||
|
||||
CharState_Hit,
|
||||
CharState_KnockDown,
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue