1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-24 14:23:54 +00:00

Merge remote-tracking branch 'upstream/master'

This commit is contained in:
mrcheko 2014-05-06 20:06:55 +04:00
commit 6590eb6727
95 changed files with 1635 additions and 1128 deletions

View file

@ -86,8 +86,6 @@ option(BUILD_UNITTESTS "Enable Unittests with Google C++ Unittest ang GMock fram
# Sound source selection # Sound source selection
option(USE_FFMPEG "use ffmpeg for sound" ON) option(USE_FFMPEG "use ffmpeg for sound" ON)
option(USE_AUDIERE "use audiere for sound" ON)
option(USE_MPG123 "use mpg123 + libsndfile for sound" ON)
# OS X deployment # OS X deployment
option(OPENMW_OSX_DEPLOYMENT OFF) option(OPENMW_OSX_DEPLOYMENT OFF)
@ -171,27 +169,6 @@ if (USE_FFMPEG)
endif (FFMPEG_FOUND) endif (FFMPEG_FOUND)
endif (USE_FFMPEG) endif (USE_FFMPEG)
if (USE_AUDIERE AND NOT GOT_SOUND_INPUT)
find_package(Audiere)
if (AUDIERE_FOUND)
set(SOUND_INPUT_INCLUDES ${SOUND_INPUT_INCLUDES} ${AUDIERE_INCLUDE_DIR})
set(SOUND_INPUT_LIBRARY ${SOUND_INPUT_LIBRARY} ${AUDIERE_LIBRARY})
set(SOUND_DEFINE ${SOUND_DEFINE} -DOPENMW_USE_AUDIERE)
set(GOT_SOUND_INPUT 1)
endif (AUDIERE_FOUND)
endif (USE_AUDIERE AND NOT GOT_SOUND_INPUT)
if (USE_MPG123 AND NOT GOT_SOUND_INPUT)
find_package(MPG123 REQUIRED)
find_package(SNDFILE REQUIRED)
if (MPG123_FOUND AND SNDFILE_FOUND)
set(SOUND_INPUT_INCLUDES ${SOUND_INPUT_INCLUDES} ${MPG123_INCLUDE_DIR} ${SNDFILE_INCLUDE_DIR})
set(SOUND_INPUT_LIBRARY ${SOUND_INPUT_LIBRARY} ${MPG123_LIBRARY} ${SNDFILE_LIBRARY})
set(SOUND_DEFINE ${SOUND_DEFINE} -DOPENMW_USE_MPG123)
set(GOT_SOUND_INPUT 1)
endif (MPG123_FOUND AND SNDFILE_FOUND)
endif (USE_MPG123 AND NOT GOT_SOUND_INPUT)
if (NOT GOT_SOUND_INPUT) if (NOT GOT_SOUND_INPUT)
message(WARNING "--------------------") message(WARNING "--------------------")
message(WARNING "Failed to find any sound input packages") message(WARNING "Failed to find any sound input packages")
@ -434,7 +411,6 @@ IF(NOT WIN32 AND NOT APPLE)
# Install licenses # Install licenses
INSTALL(FILES "DejaVu Font License.txt" DESTINATION "${LICDIR}" ) INSTALL(FILES "DejaVu Font License.txt" DESTINATION "${LICDIR}" )
INSTALL(FILES "OFL.txt" DESTINATION "${LICDIR}" )
INSTALL(FILES "extern/shiny/License.txt" DESTINATION "${LICDIR}" RENAME "Shiny License.txt" ) INSTALL(FILES "extern/shiny/License.txt" DESTINATION "${LICDIR}" RENAME "Shiny License.txt" )
ENDIF (DPKG_PROGRAM) ENDIF (DPKG_PROGRAM)

View file

@ -60,7 +60,7 @@ opencs_hdrs_noqt (view/doc
opencs_units (view/world opencs_units (view/world
table tablesubview scriptsubview util regionmapsubview tablebottombox creator genericcreator table tablesubview scriptsubview util regionmapsubview tablebottombox creator genericcreator
cellcreator referenceablecreator referencecreator scenesubview scenetoolbar scenetool cellcreator referenceablecreator referencecreator scenesubview scenetoolbar scenetool
scenetoolmode infocreator scriptedit dialoguesubview previewsubview regionmap scenetoolmode infocreator scriptedit dialoguesubview previewsubview regionmap dragrecordtable
) )
opencs_units (view/render opencs_units (view/render
@ -97,6 +97,7 @@ opencs_units (view/settings
listview listview
rangeview rangeview
resizeablestackedwidget resizeablestackedwidget
spinbox
) )
opencs_units_noqt (view/settings opencs_units_noqt (view/settings

View file

@ -1,13 +1,8 @@
#include "setting.hpp" #include "setting.hpp"
#include "support.hpp" #include "support.hpp"
CSMSettings::Setting::Setting()
{
buildDefaultSetting();
}
CSMSettings::Setting::Setting(SettingType typ, const QString &settingName, CSMSettings::Setting::Setting(SettingType typ, const QString &settingName,
const QString &pageName, const QStringList &values) const QString &pageName)
: mIsEditorSetting (false) : mIsEditorSetting (false)
{ {
buildDefaultSetting(); buildDefaultSetting();
@ -19,10 +14,9 @@ CSMSettings::Setting::Setting(SettingType typ, const QString &settingName,
setProperty (Property_IsMultiValue, QVariant(true).toString()); setProperty (Property_IsMultiValue, QVariant(true).toString());
//view type is related to setting type by an order of magnitude //view type is related to setting type by an order of magnitude
setProperty (Property_ViewType, QVariant (settingType / 10).toString()); setProperty (Property_SettingType, QVariant (settingType).toString());
setProperty (Property_Page, pageName); setProperty (Property_Page, pageName);
setProperty (Property_Name, settingName); setProperty (Property_Name, settingName);
setProperty (Property_DeclaredValues, values);
} }
void CSMSettings::Setting::buildDefaultSetting() void CSMSettings::Setting::buildDefaultSetting()
@ -73,6 +67,11 @@ int CSMSettings::Setting::columnSpan() const
return property (Property_ColumnSpan).at(0).toInt(); return property (Property_ColumnSpan).at(0).toInt();
} }
void CSMSettings::Setting::setDeclaredValues (QStringList list)
{
setProperty (Property_DeclaredValues, list);
}
QStringList CSMSettings::Setting::declaredValues() const QStringList CSMSettings::Setting::declaredValues() const
{ {
return property (Property_DeclaredValues); return property (Property_DeclaredValues);
@ -96,6 +95,16 @@ QStringList CSMSettings::Setting::property (SettingProperty prop) const
return mProperties.at(prop); return mProperties.at(prop);
} }
void CSMSettings::Setting::setDefaultValue (int value)
{
setDefaultValues (QStringList() << QVariant (value).toString());
}
void CSMSettings::Setting::setDefaultValue (double value)
{
setDefaultValues (QStringList() << QVariant (value).toString());
}
void CSMSettings::Setting::setDefaultValue (const QString &value) void CSMSettings::Setting::setDefaultValue (const QString &value)
{ {
setDefaultValues (QStringList() << value); setDefaultValues (QStringList() << value);
@ -165,6 +174,16 @@ bool CSMSettings::Setting::serializable() const
return (property (Property_Serializable).at(0) == "true"); return (property (Property_Serializable).at(0) == "true");
} }
void CSMSettings::Setting::setSpecialValueText(const QString &text)
{
setProperty (Property_SpecialValueText, text);
}
QString CSMSettings::Setting::specialValueText() const
{
return property (Property_SpecialValueText).at(0);
}
void CSMSettings::Setting::setName (const QString &value) void CSMSettings::Setting::setName (const QString &value)
{ {
setProperty (Property_Name, value); setProperty (Property_Name, value);
@ -185,6 +204,16 @@ QString CSMSettings::Setting::page() const
return property (Property_Page).at(0); return property (Property_Page).at(0);
} }
void CSMSettings::Setting::setPrefix (const QString &value)
{
setProperty (Property_Prefix, value);
}
QString CSMSettings::Setting::prefix() const
{
return property (Property_Prefix).at(0);
}
void CSMSettings::Setting::setRowSpan (const int value) void CSMSettings::Setting::setRowSpan (const int value)
{ {
setProperty (Property_RowSpan, value); setProperty (Property_RowSpan, value);
@ -195,15 +224,106 @@ int CSMSettings::Setting::rowSpan () const
return property (Property_RowSpan).at(0).toInt(); return property (Property_RowSpan).at(0).toInt();
} }
void CSMSettings::Setting::setViewType (int vType) void CSMSettings::Setting::setSingleStep (int value)
{ {
setProperty (Property_ViewType, vType); setProperty (Property_SingleStep, value);
}
void CSMSettings::Setting::setSingleStep (double value)
{
setProperty (Property_SingleStep, value);
}
QString CSMSettings::Setting::singleStep() const
{
return property (Property_SingleStep).at(0);
}
void CSMSettings::Setting::setSuffix (const QString &value)
{
setProperty (Property_Suffix, value);
}
QString CSMSettings::Setting::suffix() const
{
return property (Property_Suffix).at(0);
}
void CSMSettings::Setting::setTickInterval (int value)
{
setProperty (Property_TickInterval, value);
}
int CSMSettings::Setting::tickInterval () const
{
return property (Property_TickInterval).at(0).toInt();
}
void CSMSettings::Setting::setTicksAbove (bool state)
{
setProperty (Property_TicksAbove, state);
}
bool CSMSettings::Setting::ticksAbove() const
{
return (property (Property_TicksAbove).at(0) == "true");
}
void CSMSettings::Setting::setTicksBelow (bool state)
{
setProperty (Property_TicksBelow, state);
}
bool CSMSettings::Setting::ticksBelow() const
{
return (property (Property_TicksBelow).at(0) == "true");
}
void CSMSettings::Setting::setType (int settingType)
{
setProperty (Property_SettingType, settingType);
}
CSMSettings::SettingType CSMSettings::Setting::type() const
{
return static_cast <CSMSettings::SettingType> ( property (
Property_SettingType).at(0).toInt());
}
void CSMSettings::Setting::setMaximum (int value)
{
setProperty (Property_Maximum, value);
}
void CSMSettings::Setting::setMaximum (double value)
{
setProperty (Property_Maximum, value);
}
QString CSMSettings::Setting::maximum() const
{
return property (Property_Maximum).at(0);
}
void CSMSettings::Setting::setMinimum (int value)
{
setProperty (Property_Minimum, value);
}
void CSMSettings::Setting::setMinimum (double value)
{
setProperty (Property_Minimum, value);
}
QString CSMSettings::Setting::minimum() const
{
return property (Property_Minimum).at(0);
} }
CSVSettings::ViewType CSMSettings::Setting::viewType() const CSVSettings::ViewType CSMSettings::Setting::viewType() const
{ {
return static_cast <CSVSettings::ViewType> return static_cast <CSVSettings::ViewType> ( property (
(property(Property_ViewType).at(0).toInt()); Property_SettingType).at(0).toInt() / 10);
} }
void CSMSettings::Setting::setViewColumn (int value) void CSMSettings::Setting::setViewColumn (int value)
@ -241,6 +361,17 @@ int CSMSettings::Setting::widgetWidth() const
{ {
return property (Property_WidgetWidth).at(0).toInt(); return property (Property_WidgetWidth).at(0).toInt();
} }
void CSMSettings::Setting::setWrapping (bool state)
{
setProperty (Property_Wrapping, state);
}
bool CSMSettings::Setting::wrapping() const
{
return (property (Property_Wrapping).at(0) == "true");
}
void CSMSettings::Setting::setProperty (SettingProperty prop, bool value) void CSMSettings::Setting::setProperty (SettingProperty prop, bool value)
{ {
setProperty (prop, QStringList() << QVariant (value).toString()); setProperty (prop, QStringList() << QVariant (value).toString());
@ -251,6 +382,11 @@ void CSMSettings::Setting::setProperty (SettingProperty prop, int value)
setProperty (prop, QStringList() << QVariant (value).toString()); setProperty (prop, QStringList() << QVariant (value).toString());
} }
void CSMSettings::Setting::setProperty (SettingProperty prop, double value)
{
setProperty (prop, QStringList() << QVariant (value).toString());
}
void CSMSettings::Setting::setProperty (SettingProperty prop, void CSMSettings::Setting::setProperty (SettingProperty prop,
const QString &value) const QString &value)
{ {
@ -263,18 +399,3 @@ void CSMSettings::Setting::setProperty (SettingProperty prop,
if (prop < mProperties.size()) if (prop < mProperties.size())
mProperties.replace (prop, value); mProperties.replace (prop, value);
} }
QDataStream &operator <<(QDataStream &stream, const CSMSettings::Setting& setting)
{
// stream << setting.properties();
// stream << setting.proxies();
return stream;
}
QDataStream &operator >>(QDataStream& stream, CSMSettings::Setting& setting)
{
// stream >> setting.properties();
// stream >> setting.proxies();
return stream;
}

View file

@ -27,12 +27,8 @@ namespace CSMSettings
public: public:
explicit Setting();
explicit Setting(SettingType typ, const QString &settingName, explicit Setting(SettingType typ, const QString &settingName,
const QString &pageName, const QString &pageName);
const QStringList &values = QStringList());
void addProxy (const Setting *setting, const QStringList &vals); void addProxy (const Setting *setting, const QStringList &vals);
void addProxy (const Setting *setting, const QList <QStringList> &list); void addProxy (const Setting *setting, const QList <QStringList> &list);
@ -49,6 +45,8 @@ namespace CSMSettings
void setDefinedValues (QStringList list); void setDefinedValues (QStringList list);
QStringList definedValues() const; QStringList definedValues() const;
void setDefaultValue (int value);
void setDefaultValue (double value);
void setDefaultValue (const QString &value); void setDefaultValue (const QString &value);
void setDefaultValues (const QStringList &values); void setDefaultValues (const QStringList &values);
@ -66,12 +64,26 @@ namespace CSMSettings
void setIsMultiValue (bool state); void setIsMultiValue (bool state);
bool isMultiValue() const; bool isMultiValue() const;
void setMask (const QString &value);
QString mask() const;
void setMaximum (int value);
void setMaximum (double value);
QString maximum() const;
void setMinimum (int value);
void setMinimum (double value);
QString minimum() const;
void setName (const QString &value); void setName (const QString &value);
QString name() const; QString name() const;
void setPage (const QString &value); void setPage (const QString &value);
QString page() const; QString page() const;
void setPrefix (const QString &value);
QString prefix() const;
void setRowSpan (const int value); void setRowSpan (const int value);
int rowSpan() const; int rowSpan() const;
@ -80,6 +92,25 @@ namespace CSMSettings
void setSerializable (bool state); void setSerializable (bool state);
bool serializable() const; bool serializable() const;
void setSpecialValueText (const QString &text);
QString specialValueText() const;
void setSingleStep (int value);
void setSingleStep (double value);
QString singleStep() const;
void setSuffix (const QString &value);
QString suffix() const;
void setTickInterval (int value);
int tickInterval() const;
void setTicksAbove (bool state);
bool ticksAbove() const;
void setTicksBelow (bool state);
bool ticksBelow() const;
void setViewColumn (int value); void setViewColumn (int value);
int viewColumn() const; int viewColumn() const;
@ -88,9 +119,14 @@ namespace CSMSettings
void setViewRow (int value); void setViewRow (int value);
int viewRow() const; int viewRow() const;
void setViewType (int vType); void setType (int settingType);
CSMSettings::SettingType type() const;
CSVSettings::ViewType viewType() const; CSVSettings::ViewType viewType() const;
void setWrapping (bool state);
bool wrapping() const;
void setWidgetWidth (int value); void setWidgetWidth (int value);
int widgetWidth() const; int widgetWidth() const;
@ -100,6 +136,7 @@ namespace CSMSettings
///boilerplate code to convert setting values of common types ///boilerplate code to convert setting values of common types
void setProperty (SettingProperty prop, bool value); void setProperty (SettingProperty prop, bool value);
void setProperty (SettingProperty prop, int value); void setProperty (SettingProperty prop, int value);
void setProperty (SettingProperty prop, double value);
void setProperty (SettingProperty prop, const QString &value); void setProperty (SettingProperty prop, const QString &value);
void setProperty (SettingProperty prop, const QStringList &value); void setProperty (SettingProperty prop, const QStringList &value);
@ -111,9 +148,4 @@ namespace CSMSettings
}; };
} }
Q_DECLARE_METATYPE(CSMSettings::Setting)
QDataStream &operator <<(QDataStream &stream, const CSMSettings::Setting& setting);
QDataStream &operator >>(QDataStream &stream, CSMSettings::Setting& setting);
#endif // CSMSETTINGS_SETTING_HPP #endif // CSMSETTINGS_SETTING_HPP

View file

@ -30,8 +30,7 @@ void CSMSettings::SettingManager::dumpModel()
} }
CSMSettings::Setting *CSMSettings::SettingManager::createSetting CSMSettings::Setting *CSMSettings::SettingManager::createSetting
(CSMSettings::SettingType typ, const QString &page, const QString &name, (CSMSettings::SettingType typ, const QString &page, const QString &name)
const QStringList &values)
{ {
//get list of all settings for the current setting name //get list of all settings for the current setting name
if (findSetting (page, name)) if (findSetting (page, name))
@ -41,7 +40,8 @@ CSMSettings::Setting *CSMSettings::SettingManager::createSetting
return 0; return 0;
} }
Setting *setting = new Setting (typ, name, page, values); Setting *setting = new Setting (typ, name, page);
//add declaration to the model //add declaration to the model
mSettings.append (setting); mSettings.append (setting);

View file

@ -46,8 +46,7 @@ namespace CSMSettings
///add a new setting to the model and return it ///add a new setting to the model and return it
Setting *createSetting (CSMSettings::SettingType typ, Setting *createSetting (CSMSettings::SettingType typ,
const QString &page, const QString &name, const QString &page, const QString &name);
const QStringList &values = QStringList());
///add definitions to the settings specified in the page map ///add definitions to the settings specified in the page map
void addDefinitions (DefinitionPageMap &pageMap); void addDefinitions (DefinitionPageMap &pageMap);

View file

@ -27,7 +27,7 @@ namespace CSMSettings
{ {
Property_Name = 0, Property_Name = 0,
Property_Page = 1, Property_Page = 1,
Property_ViewType = 2, Property_SettingType = 2,
Property_IsMultiValue = 3, Property_IsMultiValue = 3,
Property_IsMultiLine = 4, Property_IsMultiLine = 4,
Property_WidgetWidth = 5, Property_WidgetWidth = 5,
@ -37,12 +37,22 @@ namespace CSMSettings
Property_Serializable = 9, Property_Serializable = 9,
Property_ColumnSpan = 10, Property_ColumnSpan = 10,
Property_RowSpan = 11, Property_RowSpan = 11,
Property_Minimum = 12,
Property_Maximum = 13,
Property_SpecialValueText = 14,
Property_Prefix = 15,
Property_Suffix = 16,
Property_SingleStep = 17,
Property_Wrapping = 18,
Property_TickInterval = 19,
Property_TicksAbove = 20,
Property_TicksBelow = 21,
//Stringlists should always be the last items //Stringlists should always be the last items
Property_DefaultValues = 12, Property_DefaultValues = 22,
Property_DeclaredValues = 13, Property_DeclaredValues = 23,
Property_DefinedValues = 14, Property_DefinedValues = 24,
Property_Proxies = 15 Property_Proxies = 25
}; };
enum SettingType enum SettingType
@ -64,10 +74,12 @@ namespace CSMSettings
Type_ListView = 10, Type_ListView = 10,
Type_ComboBox = 11, Type_ComboBox = 11,
Type_SpinBox = 21, Type_SpinBox = 21,
Type_Slider = 23, Type_DoubleSpinBox = 23,
Type_Dial = 24, Type_Slider = 25,
Type_Dial = 27,
Type_TextArea = 30, Type_TextArea = 30,
Type_LineEdit = 31 Type_LineEdit = 31,
Type_Undefined = 40
}; };
enum MergeMethod enum MergeMethod
@ -97,7 +109,7 @@ namespace CSVSettings
}; };
} }
//
namespace CSMSettings namespace CSMSettings
{ {
struct PropertyDefaultValues struct PropertyDefaultValues
@ -109,9 +121,11 @@ namespace CSMSettings
const QString sPropertyNames[] = const QString sPropertyNames[] =
{ {
"name", "page", "view_type", "is_multi_value", "name", "page", "setting_type", "is_multi_value",
"is_multi_line", "widget_width", "view_row", "view_column", "delimiter", "is_multi_line", "widget_width", "view_row", "view_column", "delimiter",
"is_serializable","column_span", "row_span", "is_serializable","column_span", "row_span", "minimum", "maximum",
"special_value_text", "prefix", "suffix", "single_step", "wrapping",
"tick_interval", "ticks_above", "ticks_below",
"defaults", "declarations", "definitions", "proxies" "defaults", "declarations", "definitions", "proxies"
}; };
@ -119,16 +133,26 @@ namespace CSMSettings
{ {
"", //name "", //name
"", //page "", //page
"0", //view type "40", //setting type
"false", //multivalue "false", //multivalue
"false", //multiline "false", //multiline
"0", //widget width "7", //widget width
"-1", //view row "-1", //view row
"-1", //view column "-1", //view column
",", //delimiter ",", //delimiter
"true", //serialized "true", //serialized
"1", //column span "1", //column span
"1", //row span "1", //row span
"0", //value range
"0", //value minimum
"0", //value maximum
"", //special text
"", //prefix
"", //suffix
"false", //wrapping
"1", //tick interval
"false", //ticks above
"true", //ticks below
"", //default values "", //default values
"", //declared values "", //declared values
"", //defined values "", //defined values

View file

@ -51,7 +51,7 @@ void CSMSettings::UserSettings::buildSettingModelDefaults()
Setting *height = createSetting (Type_LineEdit, section, "Height"); Setting *height = createSetting (Type_LineEdit, section, "Height");
width->setWidgetWidth (5); width->setWidgetWidth (5);
height->setWidgetWidth (5); height->setWidgetWidth (8);
width->setDefaultValues (QStringList() << "1024"); width->setDefaultValues (QStringList() << "1024");
height->setDefaultValues (QStringList() << "768"); height->setDefaultValues (QStringList() << "768");
@ -66,13 +66,10 @@ void CSMSettings::UserSettings::buildSettingModelDefaults()
*Create the proxy setting for predefined values *Create the proxy setting for predefined values
*/ */
Setting *preDefined = createSetting (Type_ComboBox, section, Setting *preDefined = createSetting (Type_ComboBox, section,
"Pre-Defined", "Pre-Defined");
QStringList()
<< "640 x 480" preDefined->setDeclaredValues (QStringList() << "640 x 480"
<< "800 x 600" << "800 x 600" << "1024 x 768" << "1440 x 900");
<< "1024 x 768"
<< "1440 x 900"
);
preDefined->setViewLocation (1, 1); preDefined->setViewLocation (1, 1);
preDefined->setWidgetWidth (10); preDefined->setWidgetWidth (10);
@ -95,12 +92,13 @@ void CSMSettings::UserSettings::buildSettingModelDefaults()
<< defaultValue << "Icon Only" << "Text Only"; << defaultValue << "Icon Only" << "Text Only";
Setting *rsd = createSetting (Type_RadioButton, Setting *rsd = createSetting (Type_RadioButton,
section, "Record Status Display", section, "Record Status Display");
values);
Setting *ritd = createSetting (Type_RadioButton, Setting *ritd = createSetting (Type_RadioButton,
section, "Referenceable ID Type Display", section, "Referenceable ID Type Display");
values);
rsd->setDeclaredValues (values);
ritd->setDeclaredValues (values);
rsd->setEditorSetting (true); rsd->setEditorSetting (true);
ritd->setEditorSetting (true); ritd->setEditorSetting (true);
@ -108,44 +106,67 @@ void CSMSettings::UserSettings::buildSettingModelDefaults()
section = "Proxy Selection Test"; section = "Proxy Selection Test";
{ {
//create three setting objects, specifying the basic widget type, /******************************************************************
//the setting view name, the page name, and the default value * There are three types of values:
*
* Declared values
*
* Pre-determined values, typically for
* combobox drop downs and boolean (radiobutton / checkbox) labels.
* These values represent the total possible list of values that
* may define a setting. No other values are allowed.
*
* Defined values
*
* Values which represent the actual, current value of
* a setting. For settings with declared values, this must be one or
* several declared values, as appropriate.
*
* Proxy values - values the proxy master updates the proxy slave when
* it's own definition is set / changed. These are definitions for
* proxy slave settings, but must match any declared values the proxy
* slave has, if any.
*******************************************************************/
//create setting objects, specifying the basic widget type,
//the page name, and the view name
/*
Setting *masterBoolean = createSetting (Type_RadioButton, section, Setting *masterBoolean = createSetting (Type_RadioButton, section,
"Master Proxy", "Master Proxy");
QStringList()
<< "Profile One" << "Profile Two"
<< "Profile Three" << "Profile Four"
);
Setting *slaveBoolean = createSetting (Type_CheckBox, section, Setting *slaveBoolean = createSetting (Type_CheckBox, section,
"Proxy Checkboxes", "Proxy Checkboxes");
QStringList() << "One" << "Two"
<< "Three" << "Four" << "Five"
);
Setting *slaveSingleText = createSetting (Type_LineEdit, section, Setting *slaveSingleText = createSetting (Type_LineEdit, section,
"Proxy TextBox 1" "Proxy TextBox 1");
);
Setting *slaveMultiText = createSetting (Type_LineEdit, section, Setting *slaveMultiText = createSetting (Type_LineEdit, section,
"ProxyTextBox 2" "ProxyTextBox 2");
);
Setting *slaveAlphaSpinbox = createSetting (Type_SpinBox, section,
"Alpha Spinbox");
Setting *slaveIntegerSpinbox = createSetting (Type_SpinBox, section,
"Int Spinbox");
Setting *slaveDoubleSpinbox = createSetting (Type_DoubleSpinBox,
section, "Double Spinbox");
Setting *slaveSlider = createSetting (Type_Slider, section, "Slider");
Setting *slaveDial = createSetting (Type_Dial, section, "Dial");
//set declared values for selected views
masterBoolean->setDeclaredValues (QStringList()
<< "Profile One" << "Profile Two"
<< "Profile Three" << "Profile Four");
slaveBoolean->setDeclaredValues (QStringList()
<< "One" << "Two" << "Three" << "Four" << "Five");
slaveAlphaSpinbox->setDeclaredValues (QStringList()
<< "One" << "Two" << "Three" << "Four");
// There are three types of values:
//
// Declared values - Pre-determined values, typically for
// combobox drop downs and boolean (radiobutton / checkbox) labels.
// These values represent the total possible list of values that may
// define a setting. No other values are allowed.
//
// Defined values - Values which represent the atual, current value of
// a setting. For settings with declared values, this must be one or
// several declared values, as appropriate.
//
// Proxy values - values the proxy master updates the proxy slave when
// it's own definition is set / changed. These are definitions for
// proxy slave settings, but must match any declared values the proxy
// slave has, if any.
masterBoolean->addProxy (slaveBoolean, QList <QStringList>() masterBoolean->addProxy (slaveBoolean, QList <QStringList>()
<< (QStringList() << "One" << "Three") << (QStringList() << "One" << "Three")
@ -168,11 +189,47 @@ void CSMSettings::UserSettings::buildSettingModelDefaults()
<< (QStringList() << "Two" << "Four") << (QStringList() << "Two" << "Four")
); );
masterBoolean->addProxy (slaveAlphaSpinbox, QList <QStringList>()
<< (QStringList() << "Four")
<< (QStringList() << "Three")
<< (QStringList() << "Two")
<< (QStringList() << "One"));
masterBoolean->addProxy (slaveIntegerSpinbox, QList <QStringList> ()
<< (QStringList() << "0")
<< (QStringList() << "7")
<< (QStringList() << "14")
<< (QStringList() << "21"));
masterBoolean->addProxy (slaveDoubleSpinbox, QList <QStringList> ()
<< (QStringList() << "0.17")
<< (QStringList() << "0.34")
<< (QStringList() << "0.51")
<< (QStringList() << "0.68"));
masterBoolean->addProxy (slaveSlider, QList <QStringList> ()
<< (QStringList() << "25")
<< (QStringList() << "50")
<< (QStringList() << "75")
<< (QStringList() << "100")
);
masterBoolean->addProxy (slaveDial, QList <QStringList> ()
<< (QStringList() << "25")
<< (QStringList() << "50")
<< (QStringList() << "75")
<< (QStringList() << "100")
);
//settings with proxies are not serialized by default //settings with proxies are not serialized by default
//other settings non-serialized for demo purposes //other settings non-serialized for demo purposes
slaveBoolean->setSerializable (false); slaveBoolean->setSerializable (false);
slaveSingleText->setSerializable (false); slaveSingleText->setSerializable (false);
slaveMultiText->setSerializable (false); slaveMultiText->setSerializable (false);
slaveAlphaSpinbox->setSerializable (false);
slaveIntegerSpinbox->setSerializable (false);
slaveDoubleSpinbox->setSerializable (false);
slaveSlider->setSerializable (false);
slaveBoolean->setDefaultValues (QStringList() slaveBoolean->setDefaultValues (QStringList()
<< "One" << "Three" << "Five"); << "One" << "Three" << "Five");
@ -184,7 +241,39 @@ void CSMSettings::UserSettings::buildSettingModelDefaults()
slaveSingleText->setWidgetWidth (24); slaveSingleText->setWidgetWidth (24);
slaveMultiText->setWidgetWidth (24); slaveMultiText->setWidgetWidth (24);
}
slaveAlphaSpinbox->setDefaultValue ("Two");
slaveAlphaSpinbox->setWidgetWidth (20);
//slaveAlphaSpinbox->setPrefix ("No. ");
//slaveAlphaSpinbox->setSuffix ("!");
slaveAlphaSpinbox->setWrapping (true);
slaveIntegerSpinbox->setDefaultValue (14);
slaveIntegerSpinbox->setMinimum (0);
slaveIntegerSpinbox->setMaximum (58);
slaveIntegerSpinbox->setPrefix ("$");
slaveIntegerSpinbox->setSuffix (".00");
slaveIntegerSpinbox->setWidgetWidth (10);
slaveIntegerSpinbox->setSpecialValueText ("Nothing!");
slaveDoubleSpinbox->setDefaultValue (0.51);
slaveDoubleSpinbox->setSingleStep(0.17);
slaveDoubleSpinbox->setMaximum(4.0);
slaveSlider->setMinimum (0);
slaveSlider->setMaximum (100);
slaveSlider->setDefaultValue (75);
slaveSlider->setWidgetWidth (100);
slaveSlider->setTicksAbove (true);
slaveSlider->setTickInterval (25);
slaveDial->setMinimum (0);
slaveDial->setMaximum (100);
slaveDial->setSingleStep (5);
slaveDial->setDefaultValue (75);
slaveDial->setTickInterval (25);
*/
}
} }
CSMSettings::UserSettings::~UserSettings() CSMSettings::UserSettings::~UserSettings()
@ -195,13 +284,13 @@ CSMSettings::UserSettings::~UserSettings()
void CSMSettings::UserSettings::loadSettings (const QString &fileName) void CSMSettings::UserSettings::loadSettings (const QString &fileName)
{ {
mUserFilePath = QString::fromUtf8 mUserFilePath = QString::fromUtf8
(mCfgMgr.getUserConfigPath().c_str()) + fileName.toUtf8(); (mCfgMgr.getUserConfigPath().string().c_str()) + fileName.toUtf8();
QString global = QString::fromUtf8 QString global = QString::fromUtf8
(mCfgMgr.getGlobalPath().c_str()) + fileName.toUtf8(); (mCfgMgr.getGlobalPath().string().c_str()) + fileName.toUtf8();
QString local = QString::fromUtf8 QString local = QString::fromUtf8
(mCfgMgr.getLocalPath().c_str()) + fileName.toUtf8(); (mCfgMgr.getLocalPath().string().c_str()) + fileName.toUtf8();
//open user and global streams //open user and global streams
QTextStream *userStream = openFilestream (mUserFilePath, true); QTextStream *userStream = openFilestream (mUserFilePath, true);

View file

@ -453,7 +453,7 @@ CSMWorld::IdCollection<CSMFilter::Filter>& CSMWorld::Data::getFilters()
return mFilters; return mFilters;
} }
QAbstractItemModel *CSMWorld::Data::getTableModel (const UniversalId& id) QAbstractItemModel *CSMWorld::Data::getTableModel (const CSMWorld::UniversalId& id)
{ {
std::map<UniversalId::Type, QAbstractItemModel *>::iterator iter = mModelIndex.find (id.getType()); std::map<UniversalId::Type, QAbstractItemModel *>::iterator iter = mModelIndex.find (id.getType());

View file

@ -1,6 +1,9 @@
#include "tablemimedata.hpp" #include "tablemimedata.hpp"
#include <string> #include <string>
#include <QDebug>
#include "universalid.hpp" #include "universalid.hpp"
#include "columnbase.hpp" #include "columnbase.hpp"
@ -11,7 +14,7 @@ mDocument(document)
mObjectsFormats << QString::fromUtf8 (("tabledata/" + id.getTypeName()).c_str()); mObjectsFormats << QString::fromUtf8 (("tabledata/" + id.getTypeName()).c_str());
} }
CSMWorld::TableMimeData::TableMimeData (std::vector< CSMWorld::UniversalId >& id, const CSMDoc::Document& document) : CSMWorld::TableMimeData::TableMimeData (const std::vector< CSMWorld::UniversalId >& id, const CSMDoc::Document& document) :
mUniversalId (id), mDocument(document) mUniversalId (id), mDocument(document)
{ {
for (std::vector<UniversalId>::iterator it (mUniversalId.begin()); it != mUniversalId.end(); ++it) for (std::vector<UniversalId>::iterator it (mUniversalId.begin()); it != mUniversalId.end(); ++it)
@ -33,7 +36,8 @@ std::string CSMWorld::TableMimeData::getIcon() const
{ {
if (mUniversalId.empty()) if (mUniversalId.empty())
{ {
throw ("TableMimeData holds no UniversalId"); qDebug()<<"TableMimeData object does not hold any records!"; //because throwing in the event loop tends to be problematic
throw("TableMimeData object does not hold any records!");
} }
std::string tmpIcon; std::string tmpIcon;
@ -50,7 +54,7 @@ std::string CSMWorld::TableMimeData::getIcon() const
if (tmpIcon != mUniversalId[i].getIcon()) if (tmpIcon != mUniversalId[i].getIcon())
{ {
return ":/multitype.png"; //icon stolen from gnome return ":/multitype.png"; //icon stolen from gnome TODO: get new icon
} }
tmpIcon = mUniversalId[i].getIcon(); tmpIcon = mUniversalId[i].getIcon();
@ -531,4 +535,4 @@ CSMWorld::ColumnBase::Display CSMWorld::TableMimeData::convertEnums (CSMWorld::U
const CSMDoc::Document* CSMWorld::TableMimeData::getDocumentPtr() const const CSMDoc::Document* CSMWorld::TableMimeData::getDocumentPtr() const
{ {
return &mDocument; return &mDocument;
} }

View file

@ -33,7 +33,7 @@ namespace CSMWorld
public: public:
TableMimeData(UniversalId id, const CSMDoc::Document& document); TableMimeData(UniversalId id, const CSMDoc::Document& document);
TableMimeData(std::vector<UniversalId>& id, const CSMDoc::Document& document); TableMimeData(const std::vector<UniversalId>& id, const CSMDoc::Document& document);
~TableMimeData(); ~TableMimeData();
@ -56,6 +56,7 @@ namespace CSMWorld
UniversalId returnMatching(CSMWorld::ColumnBase::Display type) const; UniversalId returnMatching(CSMWorld::ColumnBase::Display type) const;
static CSMWorld::UniversalId::Type convertEnums(CSMWorld::ColumnBase::Display type); static CSMWorld::UniversalId::Type convertEnums(CSMWorld::ColumnBase::Display type);
static CSMWorld::ColumnBase::Display convertEnums(CSMWorld::UniversalId::Type type); static CSMWorld::ColumnBase::Display convertEnums(CSMWorld::UniversalId::Type type);
private: private:

View file

@ -64,6 +64,7 @@ namespace
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_TopicInfo, "TopicInfo", 0 }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_TopicInfo, "TopicInfo", 0 },
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_JournalInfo, "JournalInfo", 0 }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_JournalInfo, "JournalInfo", 0 },
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Cell, "Cell", ":./cell.png" }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Cell, "Cell", ":./cell.png" },
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Cell_Missing, "Cell", ":./cell.png" },
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Referenceable, "Referenceables", 0 }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Referenceable, "Referenceables", 0 },
{ CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Activator, "Activator", ":./activator.png" }, { CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Activator, "Activator", ":./activator.png" },
{ CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Potion, "Potion", ":./potion.png" }, { CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Potion, "Potion", ":./potion.png" },

View file

@ -60,6 +60,7 @@ namespace CSMWorld
Type_Spell, Type_Spell,
Type_Cells, Type_Cells,
Type_Cell, Type_Cell,
Type_Cell_Missing, //For cells that does not exist yet.
Type_Referenceables, Type_Referenceables,
Type_Referenceable, Type_Referenceable,
Type_Activator, Type_Activator,

View file

@ -3,8 +3,12 @@
#include <sstream> #include <sstream>
CSVRender::PagedWorldspaceWidget::PagedWorldspaceWidget (QWidget *parent) #include <QtGui/qevent.h>
: WorldspaceWidget (parent)
#include <apps/opencs/model/world/tablemimedata.hpp>
CSVRender::PagedWorldspaceWidget::PagedWorldspaceWidget (QWidget* parent, CSMDoc::Document& document)
: WorldspaceWidget (document, parent)
{} {}
void CSVRender::PagedWorldspaceWidget::useViewHint (const std::string& hint) void CSVRender::PagedWorldspaceWidget::useViewHint (const std::string& hint)
@ -44,4 +48,45 @@ void CSVRender::PagedWorldspaceWidget::setCellSelection (const CSMWorld::CellSel
{ {
mSelection = selection; mSelection = selection;
emit cellSelectionChanged (mSelection); emit cellSelectionChanged (mSelection);
}
std::pair< int, int > CSVRender::PagedWorldspaceWidget::getCoordinatesFromId (const std::string& record) const
{
std::istringstream stream (record.c_str());
char ignore;
int x, y;
stream >> ignore >> x >> y;
return std::make_pair(x, y);
}
void CSVRender::PagedWorldspaceWidget::handleDrop (const std::vector< CSMWorld::UniversalId >& data)
{
bool selectionChanged = false;
for (unsigned i = 0; i < data.size(); ++i)
{
std::pair<int, int> coordinates(getCoordinatesFromId(data[i].getId()));
if (mSelection.add(CSMWorld::CellCoordinates(coordinates.first, coordinates.second)))
{
selectionChanged = true;
}
}
if (selectionChanged)
{
emit cellSelectionChanged(mSelection);
}
}
CSVRender::WorldspaceWidget::dropRequirments CSVRender::PagedWorldspaceWidget::getDropRequirements (CSVRender::WorldspaceWidget::dropType type) const
{
switch (type)
{
case cellsExterior:
return canHandle;
case cellsInterior:
return needUnpaged;
default:
return ignored;
}
} }

View file

@ -13,17 +13,25 @@ namespace CSVRender
CSMWorld::CellSelection mSelection; CSMWorld::CellSelection mSelection;
private:
std::pair<int, int> getCoordinatesFromId(const std::string& record) const;
public: public:
PagedWorldspaceWidget (QWidget *parent); PagedWorldspaceWidget (QWidget *parent, CSMDoc::Document& document);
///< \note Sets the cell area selection to an invalid value to indicate that currently ///< \note Sets the cell area selection to an invalid value to indicate that currently
/// no cells are displayed. The cells to be displayed will be specified later through /// no cells are displayed. The cells to be displayed will be specified later through
/// hint system. /// hint system.
virtual void useViewHint (const std::string& hint); void useViewHint (const std::string& hint);
void setCellSelection (const CSMWorld::CellSelection& selection); void setCellSelection (const CSMWorld::CellSelection& selection);
virtual void handleDrop(const std::vector<CSMWorld::UniversalId>& data);
virtual dropRequirments getDropRequirements(dropType type) const;
signals: signals:
void cellSelectionChanged (const CSMWorld::CellSelection& selection); void cellSelectionChanged (const CSMWorld::CellSelection& selection);

View file

@ -320,7 +320,7 @@ namespace CSVRender
} }
if (mUpdate) if (mUpdate && mWindow)
{ {
mUpdate = false; mUpdate = false;
mWindow->update(); mWindow->update();

View file

@ -36,7 +36,7 @@ namespace CSVRender
SceneWidget(QWidget *parent); SceneWidget(QWidget *parent);
virtual ~SceneWidget(); virtual ~SceneWidget();
QPaintEngine* paintEngine() const; QPaintEngine* paintEngine() const;
CSVWorld::SceneToolMode *makeLightingSelector (CSVWorld::SceneToolbar *parent); CSVWorld::SceneToolMode *makeLightingSelector (CSVWorld::SceneToolbar *parent);
///< \attention 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

View file

@ -3,10 +3,13 @@
#include <OgreColourValue.h> #include <OgreColourValue.h>
#include <QtGui/qevent.h>
#include "../../model/doc/document.hpp" #include "../../model/doc/document.hpp"
#include "../../model/world/data.hpp" #include "../../model/world/data.hpp"
#include "../../model/world/idtable.hpp" #include "../../model/world/idtable.hpp"
#include "../../model/world/tablemimedata.hpp"
void CSVRender::UnpagedWorldspaceWidget::update() void CSVRender::UnpagedWorldspaceWidget::update()
{ {
@ -20,9 +23,8 @@ void CSVRender::UnpagedWorldspaceWidget::update()
/// \todo deal with mSunlight and mFog/mForDensity /// \todo deal with mSunlight and mFog/mForDensity
} }
CSVRender::UnpagedWorldspaceWidget::UnpagedWorldspaceWidget (const std::string& cellId, CSVRender::UnpagedWorldspaceWidget::UnpagedWorldspaceWidget (const std::string& cellId, CSMDoc::Document& document, QWidget* parent)
CSMDoc::Document& document, QWidget *parent) : WorldspaceWidget (document, parent), mCellId (cellId)
: WorldspaceWidget (parent), mCellId (cellId)
{ {
mCellsModel = &dynamic_cast<CSMWorld::IdTable&> ( mCellsModel = &dynamic_cast<CSMWorld::IdTable&> (
*document.getData().getTableModel (CSMWorld::UniversalId::Type_Cells)); *document.getData().getTableModel (CSMWorld::UniversalId::Type_Cells));
@ -63,4 +65,26 @@ void CSVRender::UnpagedWorldspaceWidget::cellRowsAboutToBeRemoved (const QModelI
if (cellIndex.row()>=start && cellIndex.row()<=end) if (cellIndex.row()>=start && cellIndex.row()<=end)
emit closeRequest(); emit closeRequest();
} }
void CSVRender::UnpagedWorldspaceWidget::handleDrop (const std::vector< CSMWorld::UniversalId >& data)
{
mCellId = data.begin()->getId();
update();
emit cellChanged(*data.begin());
}
CSVRender::WorldspaceWidget::dropRequirments CSVRender::UnpagedWorldspaceWidget::getDropRequirements (CSVRender::WorldspaceWidget::dropType type) const
{
switch(type)
{
case cellsInterior:
return canHandle;
case cellsExterior:
return needPaged;
default:
return ignored;
}
}

View file

@ -31,13 +31,21 @@ namespace CSVRender
public: public:
UnpagedWorldspaceWidget (const std::string& cellId, CSMDoc::Document& document, UnpagedWorldspaceWidget (const std::string& cellId, CSMDoc::Document& document,
QWidget *parent); QWidget *parent);
virtual dropRequirments getDropRequirements(dropType type) const;
virtual void handleDrop(const std::vector<CSMWorld::UniversalId>& data);
private slots: private slots:
void cellDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); void cellDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight);
void cellRowsAboutToBeRemoved (const QModelIndex& parent, int start, int end); void cellRowsAboutToBeRemoved (const QModelIndex& parent, int start, int end);
signals:
void cellChanged(const CSMWorld::UniversalId& id);
}; };
} }

View file

@ -5,15 +5,20 @@
#include <OgreSceneManager.h> #include <OgreSceneManager.h>
#include <OgreEntity.h> #include <OgreEntity.h>
#include "../world/scenetoolmode.hpp" #include <QtGui/qevent.h>
CSVRender::WorldspaceWidget::WorldspaceWidget (QWidget *parent) #include "../world/scenetoolmode.hpp"
: SceneWidget (parent) #include <apps/opencs/model/world/universalid.hpp>
CSVRender::WorldspaceWidget::WorldspaceWidget (const CSMDoc::Document& document, QWidget* parent)
: SceneWidget (parent), mDocument(document)
{ {
Ogre::Entity* ent = getSceneManager()->createEntity("cube", Ogre::SceneManager::PT_CUBE); Ogre::Entity* ent = getSceneManager()->createEntity("cube", Ogre::SceneManager::PT_CUBE);
ent->setMaterialName("BaseWhite"); ent->setMaterialName("BaseWhite");
getSceneManager()->getRootSceneNode()->attachObject(ent); getSceneManager()->getRootSceneNode()->attachObject(ent);
setAcceptDrops(true);
} }
void CSVRender::WorldspaceWidget::selectNavigationMode (const std::string& mode) void CSVRender::WorldspaceWidget::selectNavigationMode (const std::string& mode)
@ -46,4 +51,78 @@ CSVWorld::SceneToolMode *CSVRender::WorldspaceWidget::makeNavigationSelector (
this, SLOT (selectNavigationMode (const std::string&))); this, SLOT (selectNavigationMode (const std::string&)));
return tool; return tool;
}
CSVRender::WorldspaceWidget::dropType CSVRender::WorldspaceWidget::getDropType (
const std::vector< CSMWorld::UniversalId >& data)
{
dropType output = notCells;
bool firstIteration = true;
for (unsigned i = 0; i < data.size(); ++i)
{
if (data[i].getType() == CSMWorld::UniversalId::Type_Cell ||
data[i].getType() == CSMWorld::UniversalId::Type_Cell_Missing)
{
if (*(data[i].getId().begin()) == '#') //exterior
{
if (firstIteration)
{
output = cellsExterior;
firstIteration = false;
continue;
}
if (output == cellsInterior)
{
output = cellsMixed;
break;
} else {
output = cellsInterior;
}
} else //interior
{
if (firstIteration)
{
output = cellsInterior;
firstIteration = false;
continue;
}
if (output == cellsExterior)
{
output = cellsMixed;
break;
} else {
output = cellsInterior;
}
}
} else {
output = notCells;
break;
}
}
return output;
}
void CSVRender::WorldspaceWidget::dragEnterEvent (QDragEnterEvent* event)
{
event->accept();
}
void CSVRender::WorldspaceWidget::dragMoveEvent(QDragMoveEvent *event)
{
event->accept();
}
void CSVRender::WorldspaceWidget::dropEvent (QDropEvent* event)
{
const CSMWorld::TableMimeData* mime = dynamic_cast<const CSMWorld::TableMimeData*> (event->mimeData());
if (mime->fromDocument (mDocument))
{
emit dataDropped(mime->getData());
} //not handling drops from different documents at the moment
} }

View file

@ -6,7 +6,13 @@
#include "navigation1st.hpp" #include "navigation1st.hpp"
#include "navigationfree.hpp" #include "navigationfree.hpp"
#include "navigationorbit.hpp" #include "navigationorbit.hpp"
#include <apps/opencs/model/doc/document.hpp>
#include <apps/opencs/model/world/tablemimedata.hpp>
namespace CSMWorld
{
class UniversalId;
}
namespace CSVWorld namespace CSVWorld
{ {
class SceneToolMode; class SceneToolMode;
@ -25,7 +31,23 @@ namespace CSVRender
public: public:
WorldspaceWidget (QWidget *parent = 0); enum dropType
{
cellsMixed,
cellsInterior,
cellsExterior,
notCells
};
enum dropRequirments
{
canHandle,
needPaged,
needUnpaged,
ignored //either mixed cells, or not cells
};
WorldspaceWidget (const CSMDoc::Document& document, QWidget *parent = 0);
CSVWorld::SceneToolMode *makeNavigationSelector (CSVWorld::SceneToolbar *parent); CSVWorld::SceneToolMode *makeNavigationSelector (CSVWorld::SceneToolbar *parent);
///< \attention 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
@ -33,9 +55,26 @@ namespace CSVRender
void selectDefaultNavigationMode(); void selectDefaultNavigationMode();
static dropType getDropType(const std::vector<CSMWorld::UniversalId>& data);
virtual dropRequirments getDropRequirements(dropType type) const = 0;
virtual void useViewHint (const std::string& hint); virtual void useViewHint (const std::string& hint);
///< Default-implementation: ignored. ///< Default-implementation: ignored.
virtual void handleDrop(const std::vector<CSMWorld::UniversalId>& data) = 0;
protected:
const CSMDoc::Document& mDocument; //for checking if drop comes from same document
private:
void dragEnterEvent(QDragEnterEvent *event);
void dropEvent(QDropEvent* event);
void dragMoveEvent(QDragMoveEvent *event);
private slots: private slots:
void selectNavigationMode (const std::string& mode); void selectNavigationMode (const std::string& mode);
@ -43,6 +82,7 @@ namespace CSVRender
signals: signals:
void closeRequest(); void closeRequest();
void dataDropped(const std::vector<CSMWorld::UniversalId>& data);
}; };
} }

View file

@ -18,10 +18,19 @@ CSVSettings::BooleanView::BooleanView (CSMSettings::Setting *setting,
{ {
QAbstractButton *button = 0; QAbstractButton *button = 0;
if (isMultiValue()) switch (setting->type())
{
case CSMSettings::Type_CheckBox:
button = new QCheckBox (value, this); button = new QCheckBox (value, this);
else break;
case CSMSettings::Type_RadioButton:
button = new QRadioButton (value, this); button = new QRadioButton (value, this);
break;
default:
break;
}
connect (button, SIGNAL (clicked (bool)), connect (button, SIGNAL (clicked (bool)),
this, SLOT (slotToggled (bool))); this, SLOT (slotToggled (bool)));

View file

@ -123,10 +123,8 @@ void CSVSettings::Dialog::show()
{ {
if (pages().isEmpty()) if (pages().isEmpty())
buildPages(); buildPages();
QPoint screenCenter = QApplication::desktop()->screenGeometry().center(); QPoint screenCenter = QApplication::desktop()->screenGeometry().center();
move (screenCenter - geometry().center()); move (screenCenter - geometry().center());
QWidget::show(); QWidget::show();
} }

View file

@ -60,8 +60,10 @@ void CSVSettings::Frame::showWidgets()
QWidget *widg = static_cast <QWidget *> (obj); QWidget *widg = static_cast <QWidget *> (obj);
if (widg->property("sizePolicy").isValid()) if (widg->property("sizePolicy").isValid())
{
widg->setSizePolicy widg->setSizePolicy
(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); (QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
}
} }
layout()->activate(); layout()->activate();
setFixedSize(minimumSizeHint()); setFixedSize(minimumSizeHint());

View file

@ -7,6 +7,8 @@
#include "../../model/settings/usersettings.hpp" #include "../../model/settings/usersettings.hpp"
#include "../../model/settings/connector.hpp" #include "../../model/settings/connector.hpp"
#include "../../model/settings/support.hpp"
#include "settingwindow.hpp" #include "settingwindow.hpp"
QMap <CSVSettings::ViewType, CSVSettings::IViewFactory *> QMap <CSVSettings::ViewType, CSVSettings::IViewFactory *>

View file

@ -1,88 +1,198 @@
#include <QHBoxLayout> #include <QHBoxLayout>
#include <QVBoxLayout> #include <QVBoxLayout>
#include <QCheckBox>
#include <QRadioButton>
#include <QGroupBox> #include <QGroupBox>
#include <QSpinBox>
#include <QAbstractButton> #include <QDoubleSpinBox>
#include <QAbstractSpinBox>
#include <QAbstractSlider>
#include <QDial>
#include <QSlider>
#include "rangeview.hpp" #include "rangeview.hpp"
#include "spinbox.hpp"
#include "../../model/settings/setting.hpp" #include "../../model/settings/setting.hpp"
#include "../../model/settings/support.hpp"
#include <QDebug>
CSVSettings::RangeView::RangeView (CSMSettings::Setting *setting, CSVSettings::RangeView::RangeView (CSMSettings::Setting *setting,
Page *parent) Page *parent)
: View (setting, parent) : mRangeWidget (0), mRangeType (setting->type()), View (setting, parent)
{ {
foreach (const QString &value, setting->declaredValues())
{
QAbstractButton *button = 0;
if (isMultiValue()) mRangeWidget = 0;
button = new QCheckBox (value, this);
else
button = new QRadioButton (value, this);
connect (button, SIGNAL (clicked (bool)), if (isMultiValue())
this, SLOT (slotToggled (bool)));
button->setObjectName (value);
addWidget (button);
mButtons[value] = button;
}
}
void CSVSettings::RangeView::slotToggled (bool state)
{
//test only for true to avoid multiple selection updates with radiobuttons
if (!isMultiValue() && !state)
return; return;
QStringList values; switch (mRangeType)
foreach (QString key, mButtons.keys())
{ {
if (mButtons.value(key)->isChecked()) case CSMSettings::Type_SpinBox:
values.append (key); case CSMSettings::Type_DoubleSpinBox:
buildSpinBox (setting);
break;
case CSMSettings::Type_Dial:
case CSMSettings::Type_Slider:
buildSlider (setting);
break;
default:
break;
} }
setSelectedValues (values, false);
mRangeWidget->setFixedWidth (widgetWidth (setting->widgetWidth()));
mRangeWidget->setObjectName (setting->name());
addWidget (mRangeWidget);
}
void CSVSettings::RangeView::buildSlider (CSMSettings::Setting *setting)
{
switch (setting->type())
{
case CSMSettings::Type_Slider:
mRangeWidget = new QSlider (Qt::Horizontal, this);
mRangeWidget->setProperty ("tickInterval", setting->tickInterval());
if (setting->ticksAbove())
{
if (setting->ticksBelow())
mRangeWidget->setProperty ("tickPosition", QSlider::TicksBothSides);
else
mRangeWidget->setProperty ("tickPosition", QSlider::TicksAbove);
}
else if (setting->ticksBelow())
mRangeWidget->setProperty ("tickPosition", QSlider::TicksBelow);
else
mRangeWidget->setProperty ("tickPosition", QSlider::NoTicks);
break;
case CSMSettings::Type_Dial:
mRangeWidget = new QDial (this);
mRangeWidget->setProperty ("wrapping", setting->wrapping());
mRangeWidget->setProperty ("notchesVisible",
(setting->ticksAbove() || setting->ticksBelow()));
break;
default:
break;
}
mRangeWidget->setProperty ("minimum", setting->minimum());
mRangeWidget->setProperty ("maximum", setting->maximum());
mRangeWidget->setProperty ("tracking", false);
mRangeWidget->setProperty ("singleStep", setting->singleStep());
connect (mRangeWidget, SIGNAL (valueChanged (int)),
this, SLOT (slotUpdateView (int)));
}
void CSVSettings::RangeView::buildSpinBox (CSMSettings::Setting *setting)
{
SpinBox *sb = 0;
switch (setting->type())
{
case CSMSettings::Type_SpinBox:
sb = new SpinBox (this);
if (!setting->declaredValues().isEmpty())
sb->setValueList (setting->declaredValues());
mRangeWidget = sb;
connect (mRangeWidget, SIGNAL (valueChanged (int)),
this, SLOT (slotUpdateView (int)));
break;
case CSMSettings::Type_DoubleSpinBox:
mRangeWidget = new QDoubleSpinBox (this);
connect (mRangeWidget, SIGNAL (valueChanged (double)),
this, SLOT (slotUpdateView (double)));
break;
default:
break;
}
//min / max values are set automatically in AlphaSpinBox
if (setting->declaredValues().isEmpty())
{
mRangeWidget->setProperty ("minimum", setting->minimum());
mRangeWidget->setProperty ("maximum", setting->maximum());
mRangeWidget->setProperty ("singleStep", setting->singleStep());
mRangeWidget->setProperty ("specialValueText",
setting->specialValueText());
}
mRangeWidget->setProperty ("prefix", setting->prefix());
mRangeWidget->setProperty ("suffix", setting->suffix());
mRangeWidget->setProperty ("wrapping", setting->wrapping());
}
void CSVSettings::RangeView::slotUpdateView (int value)
{
QString textValue = "";
QStringList list;
switch (mRangeType)
{
case CSMSettings::Type_SpinBox:
list = static_cast <SpinBox *> (mRangeWidget)->valueList();
if (!list.isEmpty())
textValue = list.at(value);
break;
default:
break;
}
if (textValue.isEmpty())
textValue = QVariant (value).toString();
setSelectedValue (textValue, false);
View::updateView();
}
void CSVSettings::RangeView::slotUpdateView (double value)
{
setSelectedValue (QVariant(value).toString(), false);
View::updateView(); View::updateView();
} }
void CSVSettings::RangeView::updateView (bool signalUpdate) const void CSVSettings::RangeView::updateView (bool signalUpdate) const
{ {
QString value;
QStringList values = selectedValues(); if (!selectedValues().isEmpty())
value = selectedValues().at(0);
foreach (const QString &buttonName, mButtons.keys()) switch (mRangeType)
{ {
QAbstractButton *button = mButtons[buttonName]; case CSMSettings::Type_SpinBox:
static_cast <SpinBox *> (mRangeWidget)->setValue (value);
break;
//if the value is not found in the list, the widget is checked false case CSMSettings::Type_DoubleSpinBox:
bool buttonValue = values.contains(buttonName); static_cast <QDoubleSpinBox *> (mRangeWidget)->setValue (value.toDouble());
break;
//skip if the butotn value will not change case CSMSettings::Type_Slider:
if (button->isChecked() == buttonValue) case CSMSettings::Type_Dial:
continue; mRangeWidget->setProperty ("value", value.toInt());
mRangeWidget->setProperty ("sliderPosition", value.toInt());
break;
//disable autoexclusive if it's enabled and we're setting default:
//the button value to false break;
bool switchExclusive = (!buttonValue && button->autoExclusive());
if (switchExclusive)
button->setAutoExclusive (false);
button->setChecked (buttonValue);
if (switchExclusive)
button->setAutoExclusive(true);
} }
View::updateView (signalUpdate); View::updateView (signalUpdate);
} }

View file

@ -1,13 +1,11 @@
#ifndef CSVSETTINGS_RANGEVIEW_HPP #ifndef CSVSETTINGS_RANGEVIEW_HPP
#define CSVSETTINGS_RANGEVIEW_HPP #define CSVSETTINGS_RANGEVIEW_HPP
#include <QWidget>
#include <QAbstractButton>
#include "view.hpp" #include "view.hpp"
#include "../../model/settings/support.hpp" #include "../../model/settings/support.hpp"
class QStringListModel; class QStringListModel;
class QAbstractSpinBox;
namespace CSVSettings namespace CSVSettings
{ {
@ -15,7 +13,8 @@ namespace CSVSettings
{ {
Q_OBJECT Q_OBJECT
QMap <QString, QAbstractButton *> mButtons; QWidget *mRangeWidget;
CSMSettings::SettingType mRangeType;
public: public:
explicit RangeView (CSMSettings::Setting *setting, explicit RangeView (CSMSettings::Setting *setting,
@ -24,8 +23,14 @@ namespace CSVSettings
protected: protected:
void updateView (bool signalUpdate = true) const; void updateView (bool signalUpdate = true) const;
void buildSlider (CSMSettings::Setting *setting);
void buildSpinBox (CSMSettings::Setting *setting);
private slots: private slots:
void slotToggled (bool state);
void slotUpdateView (int value);
void slotUpdateView (double value);
}; };
class RangeViewFactory : public QObject, public IViewFactory class RangeViewFactory : public QObject, public IViewFactory

View file

@ -0,0 +1,51 @@
#include "spinbox.hpp"
#include <QSpinBox>
#include <QLineEdit>
CSVSettings::SpinBox::SpinBox(QWidget *parent)
: mValueList(QStringList()), QSpinBox(parent)
{
setRange (0, 0);
}
QString CSVSettings::SpinBox::textFromValue(int val) const
{
if (mValueList.isEmpty())
return QVariant (val).toString();
QString value = "";
if (val < mValueList.size())
value = mValueList.at (val);
return value;
}
int CSVSettings::SpinBox::valueFromText(const QString &text) const
{
if (mValueList.isEmpty())
return -1;
if (mValueList.contains (text))
return mValueList.indexOf(text);
return -1;
}
void CSVSettings::SpinBox::setValue (const QString &value)
{
if (!mValueList.isEmpty())
{
lineEdit()->setText (value);
QSpinBox::setValue(valueFromText(value));
}
else
QSpinBox::setValue (value.toInt());
}
void CSVSettings::SpinBox::setValueList (const QStringList &list)
{
mValueList = list;
setMaximum (list.size() - 1);
}

View file

@ -0,0 +1,31 @@
#ifndef CSVSETTINGS_SPINBOX_HPP
#define CSVSETTINGS_SPINBOX_HPP
#include <QObject>
#include <QStringList>
#include <QSpinBox>
namespace CSVSettings
{
class SpinBox : public QSpinBox
{
Q_OBJECT
QStringList mValueList;
public:
explicit SpinBox(QWidget *parent = 0);
void setObjectName (const QString &name);
void setValue (const QString &value);
void setValueList (const QStringList &list);
const QStringList &valueList() const { return mValueList; }
protected:
QString textFromValue (int val) const;
int valueFromText (const QString &text) const;
};
}
#endif // CSVSETTINGS_SPINBOX_HPP

View file

@ -28,11 +28,6 @@ bool CSVSettings::TextView::isEquivalent
return (lhs.trimmed() == rhs.trimmed()); return (lhs.trimmed() == rhs.trimmed());
} }
void CSVSettings::TextView::setWidgetText (const QString &value) const
{
mTextWidget->setProperty ("text", value);
}
void CSVSettings::TextView::slotTextEdited (QString value) void CSVSettings::TextView::slotTextEdited (QString value)
{ {
QStringList values = value.split (mDelimiter, QString::SkipEmptyParts); QStringList values = value.split (mDelimiter, QString::SkipEmptyParts);
@ -51,19 +46,14 @@ void CSVSettings::TextView::updateView(bool signalUpdate) const
{ {
QString values = selectedValues().join (mDelimiter); QString values = selectedValues().join (mDelimiter);
if (isEquivalent (widgetText(), values)) if (isEquivalent (mTextWidget->property("text").toString(), values))
return; return;
setWidgetText (values); mTextWidget->setProperty("text", values);
View::updateView (signalUpdate); View::updateView (signalUpdate);
} }
QString CSVSettings::TextView::widgetText() const
{
return mTextWidget->property("text").toString();
}
CSVSettings::TextView *CSVSettings::TextViewFactory::createView CSVSettings::TextView *CSVSettings::TextViewFactory::createView
(CSMSettings::Setting *setting, (CSMSettings::Setting *setting,
Page *parent) Page *parent)

View file

@ -32,12 +32,6 @@ namespace CSVSettings
///Comparison function that returns true if the trimmed() strings ///Comparison function that returns true if the trimmed() strings
///are equal ///are equal
bool isEquivalent (const QString &lhs, const QString &rhs) const; bool isEquivalent (const QString &lhs, const QString &rhs) const;
///Convenience function to return the text of the widget
QString widgetText() const;
///Convenience function to set the text of the widget
void setWidgetText (const QString &value) const;
}; };
class TextViewFactory : public QObject, public IViewFactory class TextViewFactory : public QObject, public IViewFactory

View file

@ -192,6 +192,7 @@ bool CSVSettings::View::stringListsMatch (
QList <QStandardItem *> CSVSettings::View::toStandardItemList QList <QStandardItem *> CSVSettings::View::toStandardItemList
(const QStringList &list) const (const QStringList &list) const
{ {
QList <QStandardItem *> itemList; QList <QStandardItem *> itemList;
foreach (const QString &value, list) foreach (const QString &value, list)

View file

@ -101,7 +101,7 @@ namespace CSVSettings
void showEvent ( QShowEvent * event ); void showEvent ( QShowEvent * event );
///Virtual for updating a specific View subclass ///Virtual for updating a specific View subclass
///bool indicates whether a signal is emitted that the view was updated ///bool indicates whether viewUpdated() signal is emitted
virtual void updateView (bool signalUpdate = true) const; virtual void updateView (bool signalUpdate = true) const;
///Returns the pixel width corresponding to the specified number of ///Returns the pixel width corresponding to the specified number of

View file

@ -183,7 +183,7 @@ CSVWorld::CommandDelegate* CSVWorld::DialogueDelegateDispatcher::makeDelegate(CS
{ {
delegate = CommandDelegateFactoryCollection::get().makeDelegate ( delegate = CommandDelegateFactoryCollection::get().makeDelegate (
display, mUndoStack, mParent); display, mUndoStack, mParent);
mDelegates.insert(std::make_pair<int, CommandDelegate*>(display, delegate)); mDelegates.insert(std::make_pair(display, delegate));
} else } else
{ {
delegate = delegateIt->second; delegate = delegateIt->second;

View file

@ -0,0 +1,38 @@
#include <QDrag>
#include "../../model/world/tablemimedata.hpp"
#include "dragrecordtable.hpp"
void CSVWorld::DragRecordTable::startDrag (const CSVWorld::DragRecordTable& table)
{
CSMWorld::TableMimeData* mime = new CSMWorld::TableMimeData (table.getDraggedRecords(), mDocument);
if (mime)
{
QDrag* drag = new QDrag (this);
drag->setMimeData (mime);
drag->setPixmap (QString::fromUtf8 (mime->getIcon().c_str()));
drag->exec (Qt::CopyAction);
}
}
CSVWorld::DragRecordTable::DragRecordTable (CSMDoc::Document& document, QWidget* parent) :
mDocument(document),
QTableView(parent),
mEditLock(false)
{}
void CSVWorld::DragRecordTable::setEditLock (bool locked)
{
mEditLock = locked;
}
void CSVWorld::DragRecordTable::dragEnterEvent(QDragEnterEvent *event)
{
event->acceptProposedAction();
}
void CSVWorld::DragRecordTable::dragMoveEvent(QDragMoveEvent *event)
{
event->accept();
}

View file

@ -0,0 +1,45 @@
#ifndef CSV_WORLD_DRAGRECORDTABLE_H
#define CSV_WORLD_DRAGRECORDTABLE_H
#include <QTableView>
#include <QtGui/qevent.h>
class QWidget;
class QAction;
namespace CSMDoc
{
class Document;
}
namespace CSMWorld
{
class UniversalId;
}
namespace CSVWorld
{
class DragRecordTable : public QTableView
{
protected:
CSMDoc::Document& mDocument;
bool mEditLock;
public:
DragRecordTable(CSMDoc::Document& document, QWidget* parent = NULL);
virtual std::vector<CSMWorld::UniversalId> getDraggedRecords() const = 0;
void setEditLock(bool locked);
protected:
void startDrag(const DragRecordTable& table);
void dragEnterEvent(QDragEnterEvent *event);
void dragMoveEvent(QDragMoveEvent *event);
};
}
#endif

View file

@ -17,6 +17,7 @@
#include "../../model/world/idtable.hpp" #include "../../model/world/idtable.hpp"
#include "../../model/world/commands.hpp" #include "../../model/world/commands.hpp"
#include "../../model/world/columns.hpp" #include "../../model/world/columns.hpp"
#include "../../model/world/tablemimedata.hpp"
void CSVWorld::RegionMap::contextMenuEvent (QContextMenuEvent *event) void CSVWorld::RegionMap::contextMenuEvent (QContextMenuEvent *event)
{ {
@ -180,7 +181,7 @@ void CSVWorld::RegionMap::setRegion (const std::string& regionId)
CSVWorld::RegionMap::RegionMap (const CSMWorld::UniversalId& universalId, CSVWorld::RegionMap::RegionMap (const CSMWorld::UniversalId& universalId,
CSMDoc::Document& document, QWidget *parent) CSMDoc::Document& document, QWidget *parent)
: QTableView (parent), mEditLock (false), mDocument (document) : DragRecordTable(document, parent)
{ {
verticalHeader()->hide(); verticalHeader()->hide();
horizontalHeader()->hide(); horizontalHeader()->hide();
@ -223,11 +224,8 @@ CSVWorld::RegionMap::RegionMap (const CSMWorld::UniversalId& universalId,
mViewInTableAction = new QAction (tr ("View Cells in Table"), this); mViewInTableAction = new QAction (tr ("View Cells in Table"), this);
connect (mViewInTableAction, SIGNAL (triggered()), this, SLOT (viewInTable())); connect (mViewInTableAction, SIGNAL (triggered()), this, SLOT (viewInTable()));
addAction (mViewInTableAction); addAction (mViewInTableAction);
}
void CSVWorld::RegionMap::setEditLock (bool locked) setAcceptDrops(true);
{
mEditLock = locked;
} }
void CSVWorld::RegionMap::selectAll() void CSVWorld::RegionMap::selectAll()
@ -343,4 +341,65 @@ void CSVWorld::RegionMap::viewInTable()
hint << ")"; hint << ")";
emit editRequest (CSMWorld::UniversalId::Type_Cells, hint.str()); emit editRequest (CSMWorld::UniversalId::Type_Cells, hint.str());
}
void CSVWorld::RegionMap::mouseMoveEvent (QMouseEvent* event)
{
startDrag(*this);
}
std::vector< CSMWorld::UniversalId > CSVWorld::RegionMap::getDraggedRecords() const
{
QModelIndexList selected(getSelectedCells(true, false));
std::vector<CSMWorld::UniversalId> ids;
foreach (QModelIndex it, selected)
{
ids.push_back(
CSMWorld::UniversalId(
CSMWorld::UniversalId::Type_Cell,
model()->data(it, CSMWorld::RegionMap::Role_CellId).toString().toUtf8().constData()));
}
selected = getSelectedCells(false, true);
foreach (QModelIndex it, selected)
{
ids.push_back(
CSMWorld::UniversalId(
CSMWorld::UniversalId::Type_Cell_Missing,
model()->data(it, CSMWorld::RegionMap::Role_CellId).toString().toUtf8().constData()));
}
return ids;
}
void CSVWorld::RegionMap::dropEvent (QDropEvent* event)
{
QModelIndex index = indexAt (event->pos());
bool exists = QTableView::model()->data(index, Qt::BackgroundRole)!=QBrush (Qt::DiagCrossPattern);
if (!index.isValid() || !exists)
{
return;
}
const CSMWorld::TableMimeData* mime = dynamic_cast<const CSMWorld::TableMimeData*> (event->mimeData());
if (mime->fromDocument(mDocument) && mime->holdsType(CSMWorld::UniversalId::Type_Region))
{
CSMWorld::UniversalId record (mime->returnMatching (CSMWorld::UniversalId::Type_Region));
QAbstractItemModel *regionModel = model();
CSMWorld::IdTable *cellsModel = &dynamic_cast<CSMWorld::IdTable&> (*
mDocument.getData().getTableModel (CSMWorld::UniversalId::Type_Cells));
std::string cellId(regionModel->data (index, CSMWorld::RegionMap::Role_CellId).
toString().toUtf8().constData());
QModelIndex index2(cellsModel->getModelIndex (cellId,
cellsModel->findColumnIndex (CSMWorld::Columns::ColumnId_Region)));
mDocument.getUndoStack().push(new CSMWorld::ModifyCommand
(*cellsModel, index2, QString::fromUtf8(record.getId().c_str())));
mRegionId = record.getId();
}
} }

View file

@ -1,8 +1,14 @@
#ifndef CSV_WORLD_REGIONMAP_H #ifndef CSV_WORLD_REGIONMAP_H
#define CSV_WORLD_REGIONMAP_H #define CSV_WORLD_REGIONMAP_H
#include <cstddef>
#include <vector>
#include <QObject>
#include <QTableView> #include <QTableView>
#include "./dragrecordtable.hpp"
class QAction; class QAction;
namespace CSMDoc namespace CSMDoc
@ -17,7 +23,7 @@ namespace CSMWorld
namespace CSVWorld namespace CSVWorld
{ {
class RegionMap : public QTableView class RegionMap : public DragRecordTable
{ {
Q_OBJECT Q_OBJECT
@ -29,8 +35,6 @@ namespace CSVWorld
QAction *mUnsetRegionAction; QAction *mUnsetRegionAction;
QAction *mViewAction; QAction *mViewAction;
QAction *mViewInTableAction; QAction *mViewInTableAction;
bool mEditLock;
CSMDoc::Document& mDocument;
std::string mRegionId; std::string mRegionId;
private: private:
@ -50,12 +54,16 @@ namespace CSVWorld
void setRegion (const std::string& regionId); void setRegion (const std::string& regionId);
///< Set region Id of selected cells. ///< Set region Id of selected cells.
void mouseMoveEvent(QMouseEvent *event);
void dropEvent(QDropEvent* event);
public: public:
RegionMap (const CSMWorld::UniversalId& universalId, CSMDoc::Document& document, RegionMap (const CSMWorld::UniversalId& universalId, CSMDoc::Document& document,
QWidget *parent = 0); QWidget *parent = 0);
void setEditLock (bool locked); virtual std::vector<CSMWorld::UniversalId> getDraggedRecords() const;
signals: signals:

View file

@ -6,6 +6,7 @@
#include <QVBoxLayout> #include <QVBoxLayout>
#include <QHBoxLayout> #include <QHBoxLayout>
#include <QLabel> #include <QLabel>
#include <cassert>
#include "../../model/doc/document.hpp" #include "../../model/doc/document.hpp"
@ -18,11 +19,10 @@
#include "tablebottombox.hpp" #include "tablebottombox.hpp"
#include "creator.hpp" #include "creator.hpp"
#include "scenetoolbar.hpp"
#include "scenetoolmode.hpp" #include "scenetoolmode.hpp"
CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document)
: SubView (id) : SubView (id), mLayout(new QHBoxLayout), mDocument(document), mScene(NULL), mToolbar(NULL)
{ {
QVBoxLayout *layout = new QVBoxLayout; QVBoxLayout *layout = new QVBoxLayout;
@ -32,33 +32,35 @@ CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::D
new TableBottomBox (NullCreatorFactory(), document.getData(), document.getUndoStack(), id, new TableBottomBox (NullCreatorFactory(), document.getData(), document.getUndoStack(), id,
this), 0); this), 0);
QHBoxLayout *layout2 = new QHBoxLayout; mLayout->setContentsMargins (QMargins (0, 0, 0, 0));
layout2->setContentsMargins (QMargins (0, 0, 0, 0)); CSVRender::WorldspaceWidget* wordspaceWidget = NULL;
widgetType whatWidget;
SceneToolbar *toolbar = new SceneToolbar (48+6, this);
if (id.getId()=="sys::default") if (id.getId()=="sys::default")
{ {
CSVRender::PagedWorldspaceWidget *widget = new CSVRender::PagedWorldspaceWidget (this); whatWidget = widget_Paged;
mScene = widget;
connect (widget, SIGNAL (cellSelectionChanged (const CSMWorld::CellSelection&)), CSVRender::PagedWorldspaceWidget *newWidget = new CSVRender::PagedWorldspaceWidget (this, document);
this, SLOT (cellSelectionChanged (const CSMWorld::CellSelection&)));
wordspaceWidget = newWidget;
makeConnections(newWidget);
} }
else else
mScene = new CSVRender::UnpagedWorldspaceWidget (id.getId(), document, this); {
whatWidget = widget_Unpaged;
SceneToolMode *navigationTool = mScene->makeNavigationSelector (toolbar); CSVRender::UnpagedWorldspaceWidget *newWidget = new CSVRender::UnpagedWorldspaceWidget (id.getId(), document, this);
toolbar->addTool (navigationTool);
SceneToolMode *lightingTool = mScene->makeLightingSelector (toolbar); wordspaceWidget = newWidget;
toolbar->addTool (lightingTool);
layout2->addWidget (toolbar, 0); makeConnections(newWidget);
}
layout2->addWidget (mScene, 1); replaceToolbarAndWorldspace(wordspaceWidget, makeToolbar(wordspaceWidget, whatWidget));
layout->insertLayout (0, layout2, 1); layout->insertLayout (0, mLayout, 1);
CSVFilter::FilterBox *filterBox = new CSVFilter::FilterBox (document.getData(), this); CSVFilter::FilterBox *filterBox = new CSVFilter::FilterBox (document.getData(), this);
@ -69,10 +71,53 @@ CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::D
widget->setLayout (layout); widget->setLayout (layout);
setWidget (widget); setWidget (widget);
}
mScene->selectDefaultNavigationMode(); void CSVWorld::SceneSubView::makeConnections (CSVRender::UnpagedWorldspaceWidget* widget)
{
connect (widget, SIGNAL (closeRequest()), this, SLOT (closeRequest()));
connect (mScene, SIGNAL (closeRequest()), this, SLOT (closeRequest())); connect(widget, SIGNAL(dataDropped(const std::vector<CSMWorld::UniversalId>&)),
this, SLOT(handleDrop(const std::vector<CSMWorld::UniversalId>&)));
connect(widget, SIGNAL(cellChanged(const CSMWorld::UniversalId&)),
this, SLOT(cellSelectionChanged(const CSMWorld::UniversalId&)));
}
void CSVWorld::SceneSubView::makeConnections (CSVRender::PagedWorldspaceWidget* widget)
{
connect (widget, SIGNAL (closeRequest()), this, SLOT (closeRequest()));
connect(widget, SIGNAL(dataDropped(const std::vector<CSMWorld::UniversalId>&)),
this, SLOT(handleDrop(const std::vector<CSMWorld::UniversalId>&)));
connect (widget, SIGNAL (cellSelectionChanged (const CSMWorld::CellSelection&)),
this, SLOT (cellSelectionChanged (const CSMWorld::CellSelection&)));
}
CSVWorld::SceneToolbar* CSVWorld::SceneSubView::makeToolbar (CSVRender::WorldspaceWidget* widget, widgetType type)
{
CSVWorld::SceneToolbar* toolbar = new SceneToolbar (48+6, this);
SceneToolMode *navigationTool = widget->makeNavigationSelector (toolbar);
toolbar->addTool (navigationTool);
SceneToolMode *lightingTool = widget->makeLightingSelector (toolbar);
toolbar->addTool (lightingTool);
/* Add buttons specific to the type. For now no need for it.
*
switch (type)
{
case widget_Paged:
break;
case widget_Unpaged:
break;
}
*/
return toolbar;
} }
void CSVWorld::SceneSubView::setEditLock (bool locked) void CSVWorld::SceneSubView::setEditLock (bool locked)
@ -102,8 +147,19 @@ void CSVWorld::SceneSubView::closeRequest()
deleteLater(); deleteLater();
} }
void CSVWorld::SceneSubView::cellSelectionChanged (const CSMWorld::UniversalId& id)
{
setUniversalId(id);
std::ostringstream stream;
stream << "Scene: " << getUniversalId().getId();
setWindowTitle (QString::fromUtf8 (stream.str().c_str()));
}
void CSVWorld::SceneSubView::cellSelectionChanged (const CSMWorld::CellSelection& selection) void CSVWorld::SceneSubView::cellSelectionChanged (const CSMWorld::CellSelection& selection)
{ {
setUniversalId(CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Scene, "sys::default"));
int size = selection.getSize(); int size = selection.getSize();
std::ostringstream stream; std::ostringstream stream;
@ -126,4 +182,62 @@ void CSVWorld::SceneSubView::cellSelectionChanged (const CSMWorld::CellSelection
} }
setWindowTitle (QString::fromUtf8 (stream.str().c_str())); setWindowTitle (QString::fromUtf8 (stream.str().c_str()));
}
void CSVWorld::SceneSubView::handleDrop (const std::vector< CSMWorld::UniversalId >& data)
{
CSVRender::PagedWorldspaceWidget* pagedNewWidget = NULL;
CSVRender::UnpagedWorldspaceWidget* unPagedNewWidget = NULL;
SceneToolbar* toolbar = NULL;
switch (mScene->getDropRequirements(CSVRender::WorldspaceWidget::getDropType(data)))
{
case CSVRender::WorldspaceWidget::canHandle:
mScene->handleDrop(data);
break;
case CSVRender::WorldspaceWidget::needPaged:
pagedNewWidget = new CSVRender::PagedWorldspaceWidget(this, mDocument);
toolbar = makeToolbar(pagedNewWidget, widget_Paged);
makeConnections(pagedNewWidget);
replaceToolbarAndWorldspace(pagedNewWidget, toolbar);
mScene->handleDrop(data);
break;
case CSVRender::WorldspaceWidget::needUnpaged:
unPagedNewWidget = new CSVRender::UnpagedWorldspaceWidget(data.begin()->getId(), mDocument, this);
toolbar = makeToolbar(unPagedNewWidget, widget_Unpaged);
makeConnections(unPagedNewWidget);
replaceToolbarAndWorldspace(unPagedNewWidget, toolbar);
cellSelectionChanged(*(data.begin()));
break;
case CSVRender::WorldspaceWidget::ignored:
return;
}
}
void CSVWorld::SceneSubView::replaceToolbarAndWorldspace (CSVRender::WorldspaceWidget* widget, CSVWorld::SceneToolbar* toolbar)
{
assert(mLayout);
if (mScene)
{
mLayout->removeWidget(mScene);
mScene->deleteLater();
}
if (mToolbar)
{
mLayout->removeWidget(mToolbar);
mToolbar->deleteLater();
}
mScene = widget;
mToolbar = toolbar;
mLayout->addWidget (mToolbar, 0);
mLayout->addWidget (mScene, 1);
mScene->selectDefaultNavigationMode();
} }

View file

@ -1,7 +1,10 @@
#ifndef CSV_WORLD_SCENESUBVIEW_H #ifndef CSV_WORLD_SCENESUBVIEW_H
#define CSV_WORLD_SCENESUBVIEW_H #define CSV_WORLD_SCENESUBVIEW_H
#include <QHBoxLayout>
#include "../doc/subview.hpp" #include "../doc/subview.hpp"
#include "scenetoolbar.hpp"
class QModelIndex; class QModelIndex;
@ -18,6 +21,8 @@ namespace CSMDoc
namespace CSVRender namespace CSVRender
{ {
class WorldspaceWidget; class WorldspaceWidget;
class PagedWorldspaceWidget;
class UnpagedWorldspaceWidget;
} }
namespace CSVWorld namespace CSVWorld
@ -32,6 +37,9 @@ namespace CSVWorld
TableBottomBox *mBottom; TableBottomBox *mBottom;
CSVRender::WorldspaceWidget *mScene; CSVRender::WorldspaceWidget *mScene;
QHBoxLayout* mLayout;
CSMDoc::Document& mDocument;
SceneToolbar* mToolbar;
public: public:
@ -45,11 +53,30 @@ namespace CSVWorld
virtual void useHint (const std::string& hint); virtual void useHint (const std::string& hint);
private:
void makeConnections(CSVRender::PagedWorldspaceWidget* widget);
void makeConnections(CSVRender::UnpagedWorldspaceWidget* widget);
void replaceToolbarAndWorldspace(CSVRender::WorldspaceWidget* widget, SceneToolbar* toolbar);
enum widgetType
{
widget_Paged,
widget_Unpaged
};
SceneToolbar* makeToolbar(CSVRender::WorldspaceWidget* widget, widgetType type);
private slots: private slots:
void closeRequest(); void closeRequest();
void cellSelectionChanged (const CSMWorld::CellSelection& selection); void cellSelectionChanged (const CSMWorld::CellSelection& selection);
void cellSelectionChanged (const CSMWorld::UniversalId& id);
void handleDrop(const std::vector<CSMWorld::UniversalId>& data);
}; };
} }

View file

@ -188,8 +188,8 @@ std::vector<std::string> CSVWorld::Table::listDeletableSelectedIds() const
CSVWorld::Table::Table (const CSMWorld::UniversalId& id, CSVWorld::Table::Table (const CSMWorld::UniversalId& id,
bool createAndDelete, bool sorting, CSMDoc::Document& document) bool createAndDelete, bool sorting, CSMDoc::Document& document)
: mCreateAction (0), mCloneAction(0), mEditLock (false), mRecordStatusDisplay (0), : mCreateAction (0), mCloneAction(0), mRecordStatusDisplay (0),
mDocument (document) DragRecordTable(document)
{ {
mModel = &dynamic_cast<CSMWorld::IdTable&> (*mDocument.getData().getTableModel (id)); mModel = &dynamic_cast<CSMWorld::IdTable&> (*mDocument.getData().getTableModel (id));
@ -282,7 +282,7 @@ void CSVWorld::Table::setEditLock (bool locked)
for (std::vector<CommandDelegate *>::iterator iter (mDelegates.begin()); iter!=mDelegates.end(); ++iter) for (std::vector<CommandDelegate *>::iterator iter (mDelegates.begin()); iter!=mDelegates.end(); ++iter)
(*iter)->setEditLock (locked); (*iter)->setEditLock (locked);
mEditLock = locked; DragRecordTable::setEditLock(locked);
} }
CSMWorld::UniversalId CSVWorld::Table::getUniversalId (int row) const CSMWorld::UniversalId CSVWorld::Table::getUniversalId (int row) const
@ -518,42 +518,8 @@ void CSVWorld::Table::mouseMoveEvent (QMouseEvent* event)
{ {
if (event->buttons() & Qt::LeftButton) if (event->buttons() & Qt::LeftButton)
{ {
QModelIndexList selectedRows = selectionModel()->selectedRows(); startDrag(*this);
if (selectedRows.size() == 0)
{
return;
}
QDrag* drag = new QDrag (this);
CSMWorld::TableMimeData* mime = NULL;
if (selectedRows.size() == 1)
{
mime = new CSMWorld::TableMimeData (getUniversalId (selectedRows.begin()->row()), mDocument);
}
else
{
std::vector<CSMWorld::UniversalId> idToDrag;
foreach (QModelIndex it, selectedRows) //I had a dream. Dream where you could use C++11 in OpenMW.
{
idToDrag.push_back (getUniversalId (it.row()));
}
mime = new CSMWorld::TableMimeData (idToDrag, mDocument);
}
drag->setMimeData (mime);
drag->setPixmap (QString::fromUtf8 (mime->getIcon().c_str()));
drag->exec(Qt::CopyAction);
} }
}
void CSVWorld::Table::dragEnterEvent(QDragEnterEvent *event)
{
event->acceptProposedAction();
} }
void CSVWorld::Table::dropEvent(QDropEvent *event) void CSVWorld::Table::dropEvent(QDropEvent *event)
@ -583,11 +549,6 @@ void CSVWorld::Table::dropEvent(QDropEvent *event)
} //TODO handle drops from different document } //TODO handle drops from different document
} }
void CSVWorld::Table::dragMoveEvent(QDragMoveEvent *event)
{
event->accept();
}
std::vector<std::string> CSVWorld::Table::getColumnsWithDisplay(CSMWorld::ColumnBase::Display display) const std::vector<std::string> CSVWorld::Table::getColumnsWithDisplay(CSMWorld::ColumnBase::Display display) const
{ {
const int count = mModel->columnCount(); const int count = mModel->columnCount();
@ -605,3 +566,18 @@ std::vector<std::string> CSVWorld::Table::getColumnsWithDisplay(CSMWorld::Column
} }
return titles; return titles;
} }
std::vector< CSMWorld::UniversalId > CSVWorld::Table::getDraggedRecords() const
{
QModelIndexList selectedRows = selectionModel()->selectedRows();
std::vector<CSMWorld::UniversalId> idToDrag;
foreach (QModelIndex it, selectedRows) //I had a dream. Dream where you could use C++11 in OpenMW.
{
idToDrag.push_back (getUniversalId (it.row()));
}
return idToDrag;
}

View file

@ -4,11 +4,11 @@
#include <vector> #include <vector>
#include <string> #include <string>
#include <QTableView>
#include <QtGui/qevent.h> #include <QtGui/qevent.h>
#include "../../model/filter/node.hpp" #include "../../model/filter/node.hpp"
#include "../../model/world/columnbase.hpp" #include "../../model/world/columnbase.hpp"
#include "dragrecordtable.hpp"
class QUndoStack; class QUndoStack;
class QAction; class QAction;
@ -31,7 +31,7 @@ namespace CSVWorld
class CommandDelegate; class CommandDelegate;
///< Table widget ///< Table widget
class Table : public QTableView class Table : public DragRecordTable
{ {
Q_OBJECT Q_OBJECT
@ -47,9 +47,7 @@ namespace CSVWorld
QAction *mPreviewAction; QAction *mPreviewAction;
CSMWorld::IdTableProxyModel *mProxyModel; CSMWorld::IdTableProxyModel *mProxyModel;
CSMWorld::IdTable *mModel; CSMWorld::IdTable *mModel;
bool mEditLock;
int mRecordStatusDisplay; int mRecordStatusDisplay;
CSMDoc::Document& mDocument;
private: private:
@ -61,10 +59,6 @@ namespace CSVWorld
void mouseMoveEvent(QMouseEvent *event); void mouseMoveEvent(QMouseEvent *event);
void dragEnterEvent(QDragEnterEvent *event);
void dragMoveEvent(QDragMoveEvent *event);
void dropEvent(QDropEvent *event); void dropEvent(QDropEvent *event);
public: public:
@ -74,12 +68,14 @@ namespace CSVWorld
///< \param createAndDelete Allow creation and deletion of records. ///< \param createAndDelete Allow creation and deletion of records.
/// \param sorting Allow changing order of rows in the view via column headers. /// \param sorting Allow changing order of rows in the view via column headers.
void setEditLock (bool locked); virtual void setEditLock (bool locked);
CSMWorld::UniversalId getUniversalId (int row) const; CSMWorld::UniversalId getUniversalId (int row) const;
std::vector<std::string> getColumnsWithDisplay(CSMWorld::ColumnBase::Display display) const; std::vector<std::string> getColumnsWithDisplay(CSMWorld::ColumnBase::Display display) const;
virtual std::vector<CSMWorld::UniversalId> getDraggedRecords() const;
signals: signals:
void editRequest (const CSMWorld::UniversalId& id, const std::string& hint); void editRequest (const CSMWorld::UniversalId& id, const std::string& hint);
@ -92,6 +88,7 @@ namespace CSVWorld
/// \param modified Number of added and modified records /// \param modified Number of added and modified records
void createRequest(); void createRequest();
void cloneRequest(const CSMWorld::UniversalId&); void cloneRequest(const CSMWorld::UniversalId&);
private slots: private slots:

View file

@ -48,7 +48,7 @@ add_openmw_dir (mwscript
) )
add_openmw_dir (mwsound add_openmw_dir (mwsound
soundmanagerimp openal_output audiere_decoder mpgsnd_decoder ffmpeg_decoder soundmanagerimp openal_output ffmpeg_decoder
) )
add_openmw_dir (mwworld add_openmw_dir (mwworld
@ -67,7 +67,7 @@ add_openmw_dir (mwclass
add_openmw_dir (mwmechanics add_openmw_dir (mwmechanics
mechanicsmanagerimp stat character creaturestats magiceffects movement actors objects mechanicsmanagerimp stat character creaturestats magiceffects movement actors objects
drawstate spells activespells npcstats aipackage aisequence aipersue alchemy aiwander aitravel aifollow drawstate spells activespells npcstats aipackage aisequence aipursue alchemy aiwander aitravel aifollow
aiescort aiactivate aicombat repair enchanting pathfinding pathgrid security spellsuccess spellcasting aiescort aiactivate aicombat repair enchanting pathfinding pathgrid security spellsuccess spellcasting
disease pickpocket levelledlist combat steering obstacle disease pickpocket levelledlist combat steering obstacle
) )

View file

@ -305,6 +305,10 @@ namespace MWBase
virtual void write (ESM::ESMWriter& writer, Loading::Listener& progress) = 0; virtual void write (ESM::ESMWriter& writer, Loading::Listener& progress) = 0;
virtual void readRecord (ESM::ESMReader& reader, int32_t type) = 0; virtual void readRecord (ESM::ESMReader& reader, int32_t type) = 0;
virtual int countSavedGameRecords() const = 0;
/// Does the current stack of GUI-windows permit saving?
virtual bool isSavingAllowed() const = 0;
}; };
} }

View file

@ -624,6 +624,8 @@ namespace MWClass
if (!attacker.isEmpty() && ptr.getClass().isNpc() && ptr.getClass().getCreatureStats(ptr).getAiSetting(MWMechanics::CreatureStats::AI_Fight).getModified() <= 30) if (!attacker.isEmpty() && ptr.getClass().isNpc() && ptr.getClass().getCreatureStats(ptr).getAiSetting(MWMechanics::CreatureStats::AI_Fight).getModified() <= 30)
MWBase::Environment::get().getMechanicsManager()->commitCrime(attacker, ptr, MWBase::MechanicsManager::OT_Assault); MWBase::Environment::get().getMechanicsManager()->commitCrime(attacker, ptr, MWBase::MechanicsManager::OT_Assault);
getCreatureStats(ptr).setAttacked(true);
if(!successful) if(!successful)
{ {
// TODO: Handle HitAttemptOnMe script function // TODO: Handle HitAttemptOnMe script function
@ -659,7 +661,6 @@ namespace MWClass
{ {
MWBase::Environment::get().getDialogueManager()->say(ptr, "hit"); MWBase::Environment::get().getDialogueManager()->say(ptr, "hit");
} }
getCreatureStats(ptr).setAttacked(true);
// Check for knockdown // Check for knockdown
float agilityTerm = getCreatureStats(ptr).getAttribute(ESM::Attribute::Agility).getModified() * fKnockDownMult->getFloat(); float agilityTerm = getCreatureStats(ptr).getAttribute(ESM::Attribute::Agility).getModified() * fKnockDownMult->getFloat();

View file

@ -215,16 +215,22 @@ namespace MWGui
{ {
std::vector<std::string> matches; std::vector<std::string> matches;
listNames(); listNames();
mCommandLine->setCaption(complete( mCommandLine->getOnlyText(), matches )); std::string oldCaption = mCommandLine->getCaption();
#if 0 std::string newCaption = complete( mCommandLine->getOnlyText(), matches );
int i = 0; mCommandLine->setCaption(newCaption);
for(std::vector<std::string>::iterator it=matches.begin(); it < matches.end(); ++it,++i )
// List candidates if repeatedly pressing tab
if (oldCaption == newCaption && matches.size())
{ {
printOK( *it ); int i = 0;
if( i == 50 ) printOK("");
break; for(std::vector<std::string>::iterator it=matches.begin(); it < matches.end(); ++it,++i )
{
printOK( *it );
if( i == 50 )
break;
}
} }
#endif
} }
if(mCommandHistory.empty()) return; if(mCommandHistory.empty()) return;

View file

@ -196,6 +196,16 @@ namespace MWGui
bitmapFile->read(&textureData[0], width*height*4); bitmapFile->read(&textureData[0], width*height*4);
bitmapFile->close(); bitmapFile->close();
std::string resourceName;
if (name.size() >= 5 && Misc::StringUtils::ciEqual(name.substr(0, 5), "magic"))
resourceName = "Magic Cards";
else if (name.size() >= 7 && Misc::StringUtils::ciEqual(name.substr(0, 7), "century"))
resourceName = "Century Gothic";
else if (name.size() >= 7 && Misc::StringUtils::ciEqual(name.substr(0, 7), "daedric"))
resourceName = "Daedric";
else
return; // no point in loading it, since there is no way of using additional fonts
std::string textureName = name; std::string textureName = name;
Ogre::Image image; Ogre::Image image;
image.loadDynamicImage(&textureData[0], width, height, Ogre::PF_BYTE_RGBA); image.loadDynamicImage(&textureData[0], width, height, Ogre::PF_BYTE_RGBA);
@ -208,18 +218,11 @@ namespace MWGui
// Register the font with MyGUI // Register the font with MyGUI
MyGUI::ResourceManualFont* font = static_cast<MyGUI::ResourceManualFont*>( MyGUI::ResourceManualFont* font = static_cast<MyGUI::ResourceManualFont*>(
MyGUI::FactoryManager::getInstance().createObject("Resource", "ResourceManualFont")); MyGUI::FactoryManager::getInstance().createObject("Resource", "ResourceManualFont"));
// We need to emulate loading from XML because the data members are private as of mygui 3.2.0 // We need to emulate loading from XML because the data members are private as of mygui 3.2.0
MyGUI::xml::Document xmlDocument; MyGUI::xml::Document xmlDocument;
MyGUI::xml::ElementPtr root = xmlDocument.createRoot("ResourceManualFont"); MyGUI::xml::ElementPtr root = xmlDocument.createRoot("ResourceManualFont");
root->addAttribute("name", resourceName);
if (name.size() >= 5 && Misc::StringUtils::ciEqual(name.substr(0, 5), "magic"))
root->addAttribute("name", "Magic Cards");
else if (name.size() >= 7 && Misc::StringUtils::ciEqual(name.substr(0, 7), "century"))
root->addAttribute("name", "Century Gothic");
else if (name.size() >= 7 && Misc::StringUtils::ciEqual(name.substr(0, 7), "daedric"))
root->addAttribute("name", "Daedric");
else
return; // no point in loading it, since there is no way of using additional fonts
MyGUI::xml::ElementPtr defaultHeight = root->createChild("Property"); MyGUI::xml::ElementPtr defaultHeight = root->createChild("Property");
defaultHeight->addAttribute("key", "DefaultHeight"); defaultHeight->addAttribute("key", "DefaultHeight");
@ -285,6 +288,7 @@ namespace MWGui
font->deserialization(root, MyGUI::Version(3,2,0)); font->deserialization(root, MyGUI::Version(3,2,0));
MyGUI::ResourceManager::getInstance().removeByName(font->getResourceName());
MyGUI::ResourceManager::getInstance().addResource(font); MyGUI::ResourceManager::getInstance().addResource(font);
} }

View file

@ -35,7 +35,7 @@ namespace MWGui
, mTrading(false) , mTrading(false)
, mLastXSize(0) , mLastXSize(0)
, mLastYSize(0) , mLastYSize(0)
, mPreview(MWBase::Environment::get().getWorld ()->getPlayerPtr()) , mPreview(new MWRender::InventoryPreview(MWBase::Environment::get().getWorld ()->getPlayerPtr()))
, mPreviewDirty(true) , mPreviewDirty(true)
, mDragAndDrop(dragAndDrop) , mDragAndDrop(dragAndDrop)
, mSelectedItem(-1) , mSelectedItem(-1)
@ -91,8 +91,8 @@ namespace MWGui
mTradeModel = new TradeItemModel(new InventoryItemModel(mPtr), MWWorld::Ptr()); mTradeModel = new TradeItemModel(new InventoryItemModel(mPtr), MWWorld::Ptr());
mSortModel = new SortFilterItemModel(mTradeModel); mSortModel = new SortFilterItemModel(mTradeModel);
mItemView->setModel(mSortModel); mItemView->setModel(mSortModel);
mPreview = MWRender::InventoryPreview(mPtr); mPreview.reset(new MWRender::InventoryPreview(mPtr));
mPreview.setup(); mPreview->setup();
} }
void InventoryWindow::setGuiMode(GuiMode mode) void InventoryWindow::setGuiMode(GuiMode mode)
@ -444,7 +444,7 @@ namespace MWGui
MWWorld::Ptr InventoryWindow::getAvatarSelectedItem(int x, int y) MWWorld::Ptr InventoryWindow::getAvatarSelectedItem(int x, int y)
{ {
int slot = mPreview.getSlotSelected (x, y); int slot = mPreview->getSlotSelected (x, y);
if (slot == -1) if (slot == -1)
return MWWorld::Ptr(); return MWWorld::Ptr();
@ -493,7 +493,7 @@ namespace MWGui
mPreviewDirty = false; mPreviewDirty = false;
MyGUI::IntSize size = mAvatarImage->getSize(); MyGUI::IntSize size = mAvatarImage->getSize();
mPreview.update (size.width, size.height); mPreview->update (size.width, size.height);
mAvatarImage->setImageTexture("CharacterPreview"); mAvatarImage->setImageTexture("CharacterPreview");
mAvatarImage->setImageCoord(MyGUI::IntCoord(0, 0, std::min(512, size.width), std::min(1024, size.height))); mAvatarImage->setImageCoord(MyGUI::IntCoord(0, 0, std::min(512, size.width), std::min(1024, size.height)));

View file

@ -34,7 +34,7 @@ namespace MWGui
MWWorld::Ptr getAvatarSelectedItem(int x, int y); MWWorld::Ptr getAvatarSelectedItem(int x, int y);
void rebuildAvatar() { void rebuildAvatar() {
mPreview.rebuild(); mPreview->rebuild();
} }
TradeItemModel* getTradeModel(); TradeItemModel* getTradeModel();
@ -81,7 +81,7 @@ namespace MWGui
int mLastXSize; int mLastXSize;
int mLastYSize; int mLastYSize;
MWRender::InventoryPreview mPreview; std::auto_ptr<MWRender::InventoryPreview> mPreview;
bool mTrading; bool mTrading;

View file

@ -170,7 +170,8 @@ namespace MWGui
buttons.push_back("loadgame"); buttons.push_back("loadgame");
if (state==MWBase::StateManager::State_Running && if (state==MWBase::StateManager::State_Running &&
MWBase::Environment::get().getWorld()->getGlobalInt ("chargenstate")==-1) MWBase::Environment::get().getWorld()->getGlobalInt ("chargenstate")==-1 &&
MWBase::Environment::get().getWindowManager()->isSavingAllowed())
buttons.push_back("savegame"); buttons.push_back("savegame");
buttons.push_back("options"); buttons.push_back("options");

View file

@ -2,6 +2,8 @@
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <components/esm/quickkeys.hpp>
#include "../mwworld/inventorystore.hpp" #include "../mwworld/inventorystore.hpp"
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
@ -55,6 +57,14 @@ namespace MWGui
} }
} }
void QuickKeysMenu::clear()
{
for (int i=0; i<10; ++i)
{
unassign(mQuickKeyButtons[i], i);
}
}
QuickKeysMenu::~QuickKeysMenu() QuickKeysMenu::~QuickKeysMenu()
{ {
delete mAssignDialog; delete mAssignDialog;
@ -154,8 +164,6 @@ namespace MWGui
frame->setUserString ("ToolTipType", "ItemPtr"); frame->setUserString ("ToolTipType", "ItemPtr");
frame->setUserData(item); frame->setUserData(item);
frame->eventMouseButtonClick += MyGUI::newDelegate(this, &QuickKeysMenu::onQuickKeyButtonClicked); frame->eventMouseButtonClick += MyGUI::newDelegate(this, &QuickKeysMenu::onQuickKeyButtonClicked);
MyGUI::ImageBox* image = frame->createWidget<MyGUI::ImageBox>("ImageBox", MyGUI::IntCoord(5, 5, 32, 32), MyGUI::Align::Default); MyGUI::ImageBox* image = frame->createWidget<MyGUI::ImageBox>("ImageBox", MyGUI::IntCoord(5, 5, 32, 32), MyGUI::Align::Default);
std::string path = std::string("icons\\"); std::string path = std::string("icons\\");
path += MWWorld::Class::get(item).getInventoryIcon(item); path += MWWorld::Class::get(item).getInventoryIcon(item);
@ -165,7 +173,8 @@ namespace MWGui
image->setImageTexture (path); image->setImageTexture (path);
image->setNeedMouseFocus (false); image->setNeedMouseFocus (false);
mItemSelectionDialog->setVisible(false); if (mItemSelectionDialog)
mItemSelectionDialog->setVisible(false);
} }
void QuickKeysMenu::onAssignItemCancel() void QuickKeysMenu::onAssignItemCancel()
@ -198,7 +207,8 @@ namespace MWGui
image->setImageTexture (path); image->setImageTexture (path);
image->setNeedMouseFocus (false); image->setNeedMouseFocus (false);
mMagicSelectionDialog->setVisible(false); if (mMagicSelectionDialog)
mMagicSelectionDialog->setVisible(false);
} }
void QuickKeysMenu::onAssignMagic (const std::string& spellId) void QuickKeysMenu::onAssignMagic (const std::string& spellId)
@ -239,7 +249,8 @@ namespace MWGui
image->setImageTexture (path); image->setImageTexture (path);
image->setNeedMouseFocus (false); image->setNeedMouseFocus (false);
mMagicSelectionDialog->setVisible(false); if (mMagicSelectionDialog)
mMagicSelectionDialog->setVisible(false);
} }
void QuickKeysMenu::onAssignMagicCancel () void QuickKeysMenu::onAssignMagicCancel ()
@ -374,6 +385,110 @@ namespace MWGui
center(); center();
} }
void QuickKeysMenu::write(ESM::ESMWriter &writer)
{
writer.startRecord(ESM::REC_KEYS);
ESM::QuickKeys keys;
for (int i=0; i<10; ++i)
{
MyGUI::Button* button = mQuickKeyButtons[i];
int type = *button->getUserData<QuickKeyType>();
ESM::QuickKeys::QuickKey key;
key.mType = type;
switch (type)
{
case Type_Unassigned:
break;
case Type_Item:
case Type_MagicItem:
{
MWWorld::Ptr item = *button->getChildAt(0)->getUserData<MWWorld::Ptr>();
key.mId = item.getCellRef().mRefID;
break;
}
case Type_Magic:
std::string spellId = button->getChildAt(0)->getUserString("Spell");
key.mId = spellId;
break;
}
keys.mKeys.push_back(key);
}
keys.save(writer);
writer.endRecord(ESM::REC_KEYS);
}
void QuickKeysMenu::readRecord(ESM::ESMReader &reader, int32_t type)
{
if (type != ESM::REC_KEYS)
return;
ESM::QuickKeys keys;
keys.load(reader);
int i=0;
for (std::vector<ESM::QuickKeys::QuickKey>::const_iterator it = keys.mKeys.begin(); it != keys.mKeys.end(); ++it)
{
if (i >= 10)
return;
mSelectedIndex = i;
int keyType = it->mType;
std::string id = it->mId;
MyGUI::Button* button = mQuickKeyButtons[i];
switch (keyType)
{
case Type_Magic:
onAssignMagic(id);
break;
case Type_Item:
case Type_MagicItem:
{
// Find the item by id
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
MWWorld::InventoryStore& store = player.getClass().getInventoryStore(player);
MWWorld::Ptr item;
for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it)
{
if (Misc::StringUtils::ciEqual(it->getCellRef().mRefID, id))
{
if (item.isEmpty() ||
// Prefer the stack with the lowest remaining uses
(it->getCellRef().mCharge != -1 && (item.getCellRef().mCharge == -1 || it->getCellRef().mCharge < item.getCellRef().mCharge) ))
{
item = *it;
}
}
}
if (item.isEmpty())
unassign(button, i);
else
{
if (keyType == Type_Item)
onAssignItem(item);
else if (keyType == Type_MagicItem)
onAssignMagicItem(item);
}
break;
}
case Type_Unassigned:
unassign(button, i);
break;
}
++i;
}
}
// --------------------------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------------------------

View file

@ -41,6 +41,11 @@ namespace MWGui
}; };
void write (ESM::ESMWriter& writer);
void readRecord (ESM::ESMReader& reader, int32_t type);
void clear();
private: private:
MyGUI::EditBox* mInstructionLabel; MyGUI::EditBox* mInstructionLabel;
MyGUI::Button* mOkButton; MyGUI::Button* mOkButton;

View file

@ -17,6 +17,8 @@ namespace MWGui
void checkReferenceAvailable(); ///< closes the window, if the MW-reference has become unavailable void checkReferenceAvailable(); ///< closes the window, if the MW-reference has become unavailable
void resetReference() { mPtr = MWWorld::Ptr(); mCurrentPlayerCell = NULL; }
protected: protected:
virtual void onReferenceUnavailable() = 0; ///< called when reference has become unavailable virtual void onReferenceUnavailable() = 0; ///< called when reference has become unavailable

View file

@ -53,7 +53,7 @@ namespace MWGui
{ {
onSlotSelected(sender, pos); onSlotSelected(sender, pos);
if (MyGUI::InputManager::getInstance().isShiftPressed()) if (pos != MyGUI::ITEM_NONE && MyGUI::InputManager::getInstance().isShiftPressed())
{ {
ConfirmationDialog* dialog = MWBase::Environment::get().getWindowManager()->getConfirmationDialog(); ConfirmationDialog* dialog = MWBase::Environment::get().getWindowManager()->getConfirmationDialog();
dialog->open("#{sMessage3}"); dialog->open("#{sMessage3}");
@ -206,6 +206,13 @@ namespace MWGui
MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage65}"); MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage65}");
return; return;
} }
}
setVisible(false);
MWBase::Environment::get().getWindowManager()->removeGuiMode (MWGui::GM_MainMenu);
if (mSaving)
{
MWBase::Environment::get().getStateManager()->saveGame (mSaveNameEdit->getCaption(), mCurrentSlot); MWBase::Environment::get().getStateManager()->saveGame (mSaveNameEdit->getCaption(), mCurrentSlot);
} }
else else
@ -213,12 +220,9 @@ namespace MWGui
if (mCurrentCharacter && mCurrentSlot) if (mCurrentCharacter && mCurrentSlot)
{ {
MWBase::Environment::get().getStateManager()->loadGame (mCurrentCharacter, mCurrentSlot); MWBase::Environment::get().getStateManager()->loadGame (mCurrentCharacter, mCurrentSlot);
MWBase::Environment::get().getWindowManager()->removeGuiMode (MWGui::GM_MainMenu);
} }
} }
setVisible(false);
if (MWBase::Environment::get().getStateManager()->getState()== if (MWBase::Environment::get().getStateManager()->getState()==
MWBase::StateManager::State_NoGame) MWBase::StateManager::State_NoGame)
{ {

View file

@ -475,7 +475,7 @@ namespace MWGui
text += std::string("#DDC79E") + faction->mName; text += std::string("#DDC79E") + faction->mName;
if (expelled.find(it->first) != expelled.end()) if (expelled.find(it->first) != expelled.end())
text += "\n#{sExpelled}"; text += "\n#BF9959#{sExpelled}";
else else
{ {
text += std::string("\n#BF9959") + faction->mRanks[it->second]; text += std::string("\n#BF9959") + faction->mRanks[it->second];

View file

@ -1405,16 +1405,49 @@ namespace MWGui
void WindowManager::clear() void WindowManager::clear()
{ {
mMap->clear(); mMap->clear();
mQuickKeysMenu->clear();
mTrainingWindow->resetReference();
mDialogueWindow->resetReference();
mTradeWindow->resetReference();
mSpellBuyingWindow->resetReference();
mSpellCreationDialog->resetReference();
mEnchantingDialog->resetReference();
mContainerWindow->resetReference();
mCompanionWindow->resetReference();
mConsole->resetReference();
mGuiModes.clear();
updateVisible();
} }
void WindowManager::write(ESM::ESMWriter &writer, Loading::Listener& progress) void WindowManager::write(ESM::ESMWriter &writer, Loading::Listener& progress)
{ {
mMap->write(writer, progress); mMap->write(writer, progress);
mQuickKeysMenu->write(writer);
progress.increaseProgress();
} }
void WindowManager::readRecord(ESM::ESMReader &reader, int32_t type) void WindowManager::readRecord(ESM::ESMReader &reader, int32_t type)
{ {
mMap->readRecord(reader, type); if (type == ESM::REC_GMAP)
mMap->readRecord(reader, type);
else if (type == ESM::REC_KEYS)
mQuickKeysMenu->readRecord(reader, type);
}
int WindowManager::countSavedGameRecords() const
{
return 1 // Global map
+ 1; // QuickKeysMenu
}
bool WindowManager::isSavingAllowed() const
{
return !MyGUI::InputManager::getInstance().isModalAny()
// TODO: remove this, once we have properly serialized the state of open windows
&& (!isGuiMode() || (mGuiModes.size() == 1 && getMode() == GM_MainMenu));
} }
void WindowManager::playVideo(const std::string &name, bool allowSkipping) void WindowManager::playVideo(const std::string &name, bool allowSkipping)

View file

@ -293,6 +293,10 @@ namespace MWGui
virtual void write (ESM::ESMWriter& writer, Loading::Listener& progress); virtual void write (ESM::ESMWriter& writer, Loading::Listener& progress);
virtual void readRecord (ESM::ESMReader& reader, int32_t type); virtual void readRecord (ESM::ESMReader& reader, int32_t type);
virtual int countSavedGameRecords() const;
/// Does the current stack of GUI-windows permit saving?
virtual bool isSavingAllowed() const;
private: private:
bool mConsoleOnlyScripts; bool mConsoleOnlyScripts;

View file

@ -29,7 +29,7 @@
#include "aicombat.hpp" #include "aicombat.hpp"
#include "aifollow.hpp" #include "aifollow.hpp"
#include "aipersue.hpp" #include "aipursue.hpp"
namespace namespace
{ {
@ -226,6 +226,7 @@ namespace MWMechanics
updateDrowning(ptr, duration); updateDrowning(ptr, duration);
calculateNpcStatModifiers(ptr); calculateNpcStatModifiers(ptr);
updateEquippedLight(ptr, duration); updateEquippedLight(ptr, duration);
updateSneak(ptr);
} }
} }
@ -710,6 +711,27 @@ namespace MWMechanics
} }
} }
void Actors::updateSneak (const MWWorld::Ptr& ptr)
{
const MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
if ( player.getClass().getCreatureStats(player).getMovementFlag(MWMechanics::CreatureStats::Flag_Sneak)
&& ptr != player)
{
const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore();
int radius = esmStore.get<ESM::GameSetting>().find("fSneakUseDist")->getInt();
bool seen = false;
// am I close enough and can I see the player?
if ( (Ogre::Vector3(ptr.getRefData().getPosition().pos).squaredDistance(Ogre::Vector3(player.getRefData().getPosition().pos)) <= radius*radius)
&& MWBase::Environment::get().getMechanicsManager()->awarenessCheck(player, ptr)
&& MWBase::Environment::get().getWorld()->getLOS(player, ptr))
seen = true;
MWBase::Environment::get().getWindowManager()->setSneakVisibility(seen);
}
}
void Actors::updateCrimePersuit(const MWWorld::Ptr& ptr, float duration) void Actors::updateCrimePersuit(const MWWorld::Ptr& ptr, float duration)
{ {
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
@ -719,34 +741,33 @@ namespace MWMechanics
CreatureStats& creatureStats = MWWorld::Class::get(ptr).getCreatureStats(ptr); CreatureStats& creatureStats = MWWorld::Class::get(ptr).getCreatureStats(ptr);
NpcStats& npcStats = MWWorld::Class::get(ptr).getNpcStats(ptr); NpcStats& npcStats = MWWorld::Class::get(ptr).getNpcStats(ptr);
// If I'm a guard and I'm not hostile if (ptr.getClass().isClass(ptr, "Guard") && creatureStats.getAiSequence().getTypeId() != AiPackage::TypeIdPursue && !creatureStats.isHostile())
if (ptr.getClass().isClass(ptr, "Guard") && !creatureStats.isHostile())
{ {
/// \todo Move me! I shouldn't be here... /// \todo Move me! I shouldn't be here...
const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore(); const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore();
float cutoff = float(esmStore.get<ESM::GameSetting>().find("iCrimeThreshold")->getInt()) * float cutoff = float(esmStore.get<ESM::GameSetting>().find("iCrimeThreshold")->getInt());
float(esmStore.get<ESM::GameSetting>().find("iCrimeThresholdMultiplier")->getInt()) * // Force dialogue on sight if bounty is greater than the cutoff
esmStore.get<ESM::GameSetting>().find("fCrimeGoldDiscountMult")->getFloat(); // In vanilla morrowind, the greeting dialogue is scripted to either arrest the player (< 5000 bounty) or attack (>= 5000 bounty)
// Attack on sight if bounty is greater than the cutoff
if ( player.getClass().getNpcStats(player).getBounty() >= cutoff if ( player.getClass().getNpcStats(player).getBounty() >= cutoff
// TODO: do not run these two every frame. keep an Aware state for each actor and update it every 0.2 s or so?
&& MWBase::Environment::get().getWorld()->getLOS(ptr, player) && MWBase::Environment::get().getWorld()->getLOS(ptr, player)
&& MWBase::Environment::get().getMechanicsManager()->awarenessCheck(player, ptr)) && MWBase::Environment::get().getMechanicsManager()->awarenessCheck(player, ptr))
{ {
creatureStats.getAiSequence().stack(AiCombat(player), ptr); creatureStats.getAiSequence().stack(AiPursue(player.getClass().getId(player)), ptr);
creatureStats.setHostile(true); creatureStats.setAlarmed(true);
npcStats.setCrimeId( MWBase::Environment::get().getWorld()->getPlayer().getCrimeId() ); npcStats.setCrimeId(MWBase::Environment::get().getWorld()->getPlayer().getNewCrimeId());
} }
} }
// if I was a witness to a crime // if I was a witness to a crime
if (npcStats.getCrimeId() != -1) if (npcStats.getCrimeId() != -1)
{ {
// if you've payed for your crimes and I havent noticed // if you've paid for your crimes and I havent noticed
if( npcStats.getCrimeId() <= MWBase::Environment::get().getWorld()->getPlayer().getCrimeId() ) if( npcStats.getCrimeId() <= MWBase::Environment::get().getWorld()->getPlayer().getCrimeId() )
{ {
// Calm witness down // Calm witness down
if (ptr.getClass().isClass(ptr, "Guard")) if (ptr.getClass().isClass(ptr, "Guard"))
creatureStats.getAiSequence().stopPersue(); creatureStats.getAiSequence().stopPursuit();
creatureStats.getAiSequence().stopCombat(); creatureStats.getAiSequence().stopCombat();
// Reset factors to attack // Reset factors to attack
@ -761,13 +782,12 @@ namespace MWMechanics
else if (!creatureStats.isHostile()) else if (!creatureStats.isHostile())
{ {
if (ptr.getClass().isClass(ptr, "Guard")) if (ptr.getClass().isClass(ptr, "Guard"))
creatureStats.getAiSequence().stack(AiPersue(player.getClass().getId(player)), ptr); creatureStats.getAiSequence().stack(AiPursue(player.getClass().getId(player)), ptr);
else else
creatureStats.getAiSequence().stack(AiCombat(player), ptr); creatureStats.getAiSequence().stack(AiCombat(player), ptr);
creatureStats.setHostile(true); creatureStats.setHostile(true);
} }
} }
// if I didn't report a crime was I attacked? // if I didn't report a crime was I attacked?
else if (creatureStats.getAttacked() && !creatureStats.isHostile()) else if (creatureStats.getAttacked() && !creatureStats.isHostile())
{ {

View file

@ -44,6 +44,8 @@ namespace MWMechanics
void updateCrimePersuit (const MWWorld::Ptr& ptr, float duration); void updateCrimePersuit (const MWWorld::Ptr& ptr, float duration);
void updateSneak (const MWWorld::Ptr& ptr);
public: public:
Actors(); Actors();

View file

@ -20,7 +20,7 @@ namespace MWMechanics
TypeIdFollow = 3, TypeIdFollow = 3,
TypeIdActivate = 4, TypeIdActivate = 4,
TypeIdCombat = 5, TypeIdCombat = 5,
TypeIdPersue = 6 TypeIdPursue = 6
}; };
virtual ~AiPackage(); virtual ~AiPackage();

View file

@ -1,4 +1,4 @@
#include "aipersue.hpp" #include "aipursue.hpp"
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
@ -11,15 +11,15 @@
#include "movement.hpp" #include "movement.hpp"
#include "creaturestats.hpp" #include "creaturestats.hpp"
MWMechanics::AiPersue::AiPersue(const std::string &objectId) MWMechanics::AiPursue::AiPursue(const std::string &objectId)
: mObjectId(objectId) : mObjectId(objectId)
{ {
} }
MWMechanics::AiPersue *MWMechanics::AiPersue::clone() const MWMechanics::AiPursue *MWMechanics::AiPursue::clone() const
{ {
return new AiPersue(*this); return new AiPursue(*this);
} }
bool MWMechanics::AiPersue::execute (const MWWorld::Ptr& actor, float duration) bool MWMechanics::AiPursue::execute (const MWWorld::Ptr& actor, float duration)
{ {
MWBase::World *world = MWBase::Environment::get().getWorld(); MWBase::World *world = MWBase::Environment::get().getWorld();
ESM::Position pos = actor.getRefData().getPosition(); ESM::Position pos = actor.getRefData().getPosition();
@ -52,11 +52,13 @@ bool MWMechanics::AiPersue::execute (const MWWorld::Ptr& actor, float duration)
} }
} }
// Big TODO: Sync this with current AiFollow. Move common code to a shared base class or helpers (applies to all AI packages, way too much duplicated code)
MWWorld::Ptr target = world->getPtr(mObjectId,false); MWWorld::Ptr target = world->getPtr(mObjectId,false);
ESM::Position targetPos = target.getRefData().getPosition(); ESM::Position targetPos = target.getRefData().getPosition();
bool cellChange = cell->mData.mX != mCellX || cell->mData.mY != mCellY; bool cellChange = cell->mData.mX != mCellX || cell->mData.mY != mCellY;
if(!mPathFinder.isPathConstructed() || cellChange) if(!mPathFinder.isPathConstructed() || cellChange || mPathFinder.checkPathCompleted(pos.pos[0], pos.pos[1], pos.pos[2]))
{ {
mCellX = cell->mData.mX; mCellX = cell->mData.mX;
mCellY = cell->mData.mY; mCellY = cell->mData.mY;
@ -76,15 +78,7 @@ bool MWMechanics::AiPersue::execute (const MWWorld::Ptr& actor, float duration)
if((pos.pos[0]-targetPos.pos[0])*(pos.pos[0]-targetPos.pos[0])+ if((pos.pos[0]-targetPos.pos[0])*(pos.pos[0]-targetPos.pos[0])+
(pos.pos[1]-targetPos.pos[1])*(pos.pos[1]-targetPos.pos[1])+ (pos.pos[1]-targetPos.pos[1])*(pos.pos[1]-targetPos.pos[1])+
(pos.pos[2]-targetPos.pos[2])*(pos.pos[2]-targetPos.pos[2]) < 200*200) (pos.pos[2]-targetPos.pos[2])*(pos.pos[2]-targetPos.pos[2]) < 100*100)
{
movement.mPosition[1] = 0;
MWWorld::Ptr target = world->getPtr(mObjectId,false);
MWWorld::Class::get(target).activate(target,actor).get()->execute(actor);
return true;
}
if(mPathFinder.checkPathCompleted(pos.pos[0], pos.pos[1], pos.pos[2]))
{ {
movement.mPosition[1] = 0; movement.mPosition[1] = 0;
MWWorld::Ptr target = world->getPtr(mObjectId,false); MWWorld::Ptr target = world->getPtr(mObjectId,false);
@ -100,7 +94,7 @@ bool MWMechanics::AiPersue::execute (const MWWorld::Ptr& actor, float duration)
return false; return false;
} }
int MWMechanics::AiPersue::getTypeId() const int MWMechanics::AiPursue::getTypeId() const
{ {
return TypeIdPersue; return TypeIdPursue;
} }

View file

@ -1,5 +1,5 @@
#ifndef GAME_MWMECHANICS_AIPERSUE_H #ifndef GAME_MWMECHANICS_AIPURSUE_H
#define GAME_MWMECHANICS_AIPERSUE_H #define GAME_MWMECHANICS_AIPURSUE_H
#include "aipackage.hpp" #include "aipackage.hpp"
#include <string> #include <string>
@ -9,11 +9,11 @@
namespace MWMechanics namespace MWMechanics
{ {
class AiPersue : public AiPackage class AiPursue : public AiPackage
{ {
public: public:
AiPersue(const std::string &objectId); AiPursue(const std::string &objectId);
virtual AiPersue *clone() const; virtual AiPursue *clone() const;
virtual bool execute (const MWWorld::Ptr& actor,float duration); virtual bool execute (const MWWorld::Ptr& actor,float duration);
///< \return Package completed? ///< \return Package completed?
virtual int getTypeId() const; virtual int getTypeId() const;

View file

@ -73,9 +73,9 @@ void MWMechanics::AiSequence::stopCombat()
} }
} }
void MWMechanics::AiSequence::stopPersue() void MWMechanics::AiSequence::stopPursuit()
{ {
while (getTypeId() == AiPackage::TypeIdPersue) while (getTypeId() == AiPackage::TypeIdPursue)
{ {
delete *mPackages.begin(); delete *mPackages.begin();
mPackages.erase (mPackages.begin()); mPackages.erase (mPackages.begin());
@ -93,11 +93,16 @@ void MWMechanics::AiSequence::execute (const MWWorld::Ptr& actor,float duration)
{ {
if (!mPackages.empty()) if (!mPackages.empty())
{ {
mLastAiPackage = mPackages.front()->getTypeId(); MWMechanics::AiPackage* package = mPackages.front();
if (mPackages.front()->execute (actor,duration)) mLastAiPackage = package->getTypeId();
if (package->execute (actor,duration))
{ {
delete *mPackages.begin(); // To account for the rare case where AiPackage::execute() queued another AI package
mPackages.erase (mPackages.begin()); // (e.g. AiPursue executing a dialogue script that uses startCombat)
std::list<MWMechanics::AiPackage*>::iterator toRemove =
std::find(mPackages.begin(), mPackages.end(), package);
mPackages.erase(toRemove);
delete package;
mDone = true; mDone = true;
} }
else else
@ -118,7 +123,7 @@ void MWMechanics::AiSequence::clear()
void MWMechanics::AiSequence::stack (const AiPackage& package, const MWWorld::Ptr& actor) void MWMechanics::AiSequence::stack (const AiPackage& package, const MWWorld::Ptr& actor)
{ {
if (package.getTypeId() == AiPackage::TypeIdCombat || package.getTypeId() == AiPackage::TypeIdPersue) if (package.getTypeId() == AiPackage::TypeIdCombat || package.getTypeId() == AiPackage::TypeIdPursue)
{ {
// Notify AiWander of our current position so we can return to it after combat finished // Notify AiWander of our current position so we can return to it after combat finished
for (std::list<AiPackage *>::const_iterator iter (mPackages.begin()); iter!=mPackages.end(); ++iter) for (std::list<AiPackage *>::const_iterator iter (mPackages.begin()); iter!=mPackages.end(); ++iter)

View file

@ -50,8 +50,8 @@ namespace MWMechanics
void stopCombat(); void stopCombat();
///< Removes all combat packages until first non-combat or stack empty. ///< Removes all combat packages until first non-combat or stack empty.
void stopPersue(); void stopPursuit();
///< Removes all persue packages until first non-persue or stack empty. ///< Removes all pursue packages until first non-pursue or stack empty.
bool isPackageDone() const; bool isPackageDone() const;
///< Has a package been completed during the last update? ///< Has a package been completed during the last update?

View file

@ -489,12 +489,13 @@ CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Anim
mIdleState = CharState_Idle; mIdleState = CharState_Idle;
} }
refreshCurrentAnims(mIdleState, mMovementState, true);
if(mDeathState != CharState_None) if(mDeathState != CharState_None)
{ {
playRandomDeath(1.0f); playRandomDeath(1.0f);
} }
else
refreshCurrentAnims(mIdleState, mMovementState, true);
} }
CharacterController::~CharacterController() CharacterController::~CharacterController()

View file

@ -877,8 +877,8 @@ namespace MWMechanics
// Tell everyone, including yourself // Tell everyone, including yourself
for (std::vector<MWWorld::Ptr>::iterator it1 = neighbors.begin(); it1 != neighbors.end(); ++it1) for (std::vector<MWWorld::Ptr>::iterator it1 = neighbors.begin(); it1 != neighbors.end(); ++it1)
{ {
if ( *it == ptr if ( *it1 == ptr
|| !it->getClass().isNpc()) continue; // not the player and is an NPC || !it1->getClass().isNpc()) continue; // not the player and is an NPC
// TODO: Add more messages // TODO: Add more messages
if (type == OT_Theft) if (type == OT_Theft)

View file

@ -34,6 +34,10 @@ namespace MWRender
virtual void rebuild(); virtual void rebuild();
private:
CharacterPreview(const CharacterPreview&);
CharacterPreview& operator=(const CharacterPreview&);
protected: protected:
virtual bool renderHeadOnly() { return false; } virtual bool renderHeadOnly() { return false; }

View file

@ -563,7 +563,8 @@ void RenderingManager::configureAmbient(MWWorld::CellStore &mCell)
Ogre::ColourValue colour; Ogre::ColourValue colour;
colour.setAsABGR (mCell.getCell()->mAmbi.mSunlight); colour.setAsABGR (mCell.getCell()->mAmbi.mSunlight);
mSun->setDiffuseColour (colour); mSun->setDiffuseColour (colour);
mSun->setDirection(0,-1,0); mSun->setDirection(1,-1,-1);
sunEnable(false);
} }
} }
// Switch through lighting modes. // Switch through lighting modes.

View file

@ -28,7 +28,9 @@ RippleSimulation::RippleSimulation(Ogre::SceneManager* mainSceneManager)
mRippleAreaLength(1000), mRippleAreaLength(1000),
mImpulseSize(20), mImpulseSize(20),
mTexelOffset(0,0), mTexelOffset(0,0),
mFirstUpdate(true) mFirstUpdate(true),
mRectangle(NULL),
mImpulse(NULL)
{ {
Ogre::AxisAlignedBox aabInf; Ogre::AxisAlignedBox aabInf;
aabInf.setInfinite(); aabInf.setInfinite();
@ -105,6 +107,7 @@ RippleSimulation::RippleSimulation(Ogre::SceneManager* mainSceneManager)
RippleSimulation::~RippleSimulation() RippleSimulation::~RippleSimulation()
{ {
delete mRectangle; delete mRectangle;
delete mImpulse;
Ogre::Root::getSingleton().destroySceneManager(mSceneMgr); Ogre::Root::getSingleton().destroySceneManager(mSceneMgr);
} }

View file

@ -1,137 +0,0 @@
#ifdef OPENMW_USE_AUDIERE
#include <stdexcept>
#include <iostream>
#include "audiere_decoder.hpp"
static void fail(const std::string &msg)
{ throw std::runtime_error("Audiere exception: "+msg); }
namespace MWSound
{
class OgreFile : public audiere::File
{
Ogre::DataStreamPtr mStream;
ADR_METHOD(int) read(void* buffer, int size)
{
return mStream->read(buffer, size);
}
ADR_METHOD(bool) seek(int position, SeekMode mode)
{
if(mode == CURRENT)
mStream->seek(mStream->tell()+position);
else if(mode == BEGIN)
mStream->seek(position);
else if(mode == END)
mStream->seek(mStream->size()+position);
else
return false;
return true;
}
ADR_METHOD(int) tell()
{
return mStream->tell();
}
size_t refs;
ADR_METHOD(void) ref() { ++refs; }
ADR_METHOD(void) unref()
{
if(--refs == 0)
delete this;
}
public:
OgreFile(const Ogre::DataStreamPtr &stream)
: mStream(stream), refs(1)
{ }
virtual ~OgreFile() { }
Ogre::String getName()
{ return mStream->getName(); }
};
void Audiere_Decoder::open(const std::string &fname)
{
close();
mSoundFile = audiere::FilePtr(new OgreFile(mResourceMgr.openResource(fname)));
mSoundSource = audiere::OpenSampleSource(mSoundFile);
mSoundFileName = fname;
int channels, srate;
audiere::SampleFormat format;
mSoundSource->getFormat(channels, srate, format);
if(format == audiere::SF_S16)
mSampleType = SampleType_Int16;
else if(format == audiere::SF_U8)
mSampleType = SampleType_UInt8;
else
fail("Unsupported sample type");
if(channels == 1)
mChannelConfig = ChannelConfig_Mono;
else if(channels == 2)
mChannelConfig = ChannelConfig_Stereo;
else
fail("Unsupported channel count");
mSampleRate = srate;
}
void Audiere_Decoder::close()
{
mSoundFile = NULL;
mSoundSource = NULL;
}
std::string Audiere_Decoder::getName()
{
return mSoundFileName;
}
void Audiere_Decoder::getInfo(int *samplerate, ChannelConfig *chans, SampleType *type)
{
*samplerate = mSampleRate;
*chans = mChannelConfig;
*type = mSampleType;
}
size_t Audiere_Decoder::read(char *buffer, size_t bytes)
{
int size = bytesToFrames(bytes, mChannelConfig, mSampleType);
size = mSoundSource->read(size, buffer);
return framesToBytes(size, mChannelConfig, mSampleType);
}
void Audiere_Decoder::rewind()
{
mSoundSource->reset();
}
size_t Audiere_Decoder::getSampleOffset()
{
return 0;
}
Audiere_Decoder::Audiere_Decoder()
{
}
Audiere_Decoder::~Audiere_Decoder()
{
close();
}
}
#endif

View file

@ -1,46 +0,0 @@
#ifndef GAME_SOUND_AUDIERE_DECODER_H
#define GAME_SOUND_AUDIERE_DECODER_H
#include <OgreDataStream.h>
#include "audiere.h"
#include "sound_decoder.hpp"
namespace MWSound
{
class Audiere_Decoder : public Sound_Decoder
{
std::string mSoundFileName;
audiere::FilePtr mSoundFile;
audiere::SampleSourcePtr mSoundSource;
int mSampleRate;
SampleType mSampleType;
ChannelConfig mChannelConfig;
virtual void open(const std::string &fname);
virtual void close();
virtual std::string getName();
virtual void getInfo(int *samplerate, ChannelConfig *chans, SampleType *type);
virtual size_t read(char *buffer, size_t bytes);
virtual void rewind();
virtual size_t getSampleOffset();
Audiere_Decoder& operator=(const Audiere_Decoder &rhs);
Audiere_Decoder(const Audiere_Decoder &rhs);
Audiere_Decoder();
public:
virtual ~Audiere_Decoder();
friend class SoundManager;
};
#ifndef DEFAULT_DECODER
#define DEFAULT_DECODER (::MWSound::Audiere_Decoder)
#endif
};
#endif

View file

@ -1,247 +0,0 @@
#ifdef OPENMW_USE_MPG123
#include <stdexcept>
#include <iostream>
#include "mpgsnd_decoder.hpp"
static void fail(const std::string &msg)
{ throw std::runtime_error("MpgSnd exception: "+msg); }
namespace MWSound
{
//
// libSndFile io callbacks
//
sf_count_t MpgSnd_Decoder::ogresf_get_filelen(void *user_data)
{
Ogre::DataStreamPtr stream = static_cast<MpgSnd_Decoder*>(user_data)->mDataStream;
return stream->size();
}
sf_count_t MpgSnd_Decoder::ogresf_seek(sf_count_t offset, int whence, void *user_data)
{
Ogre::DataStreamPtr stream = static_cast<MpgSnd_Decoder*>(user_data)->mDataStream;
if(whence == SEEK_CUR)
stream->seek(stream->tell()+offset);
else if(whence == SEEK_SET)
stream->seek(offset);
else if(whence == SEEK_END)
stream->seek(stream->size()+offset);
else
return -1;
return stream->tell();
}
sf_count_t MpgSnd_Decoder::ogresf_read(void *ptr, sf_count_t count, void *user_data)
{
Ogre::DataStreamPtr stream = static_cast<MpgSnd_Decoder*>(user_data)->mDataStream;
return stream->read(ptr, count);
}
sf_count_t MpgSnd_Decoder::ogresf_write(const void*, sf_count_t, void*)
{ return -1; }
sf_count_t MpgSnd_Decoder::ogresf_tell(void *user_data)
{
Ogre::DataStreamPtr stream = static_cast<MpgSnd_Decoder*>(user_data)->mDataStream;
return stream->tell();
}
//
// libmpg13 io callbacks
//
ssize_t MpgSnd_Decoder::ogrempg_read(void *user_data, void *ptr, size_t count)
{
Ogre::DataStreamPtr stream = static_cast<MpgSnd_Decoder*>(user_data)->mDataStream;
return stream->read(ptr, count);
}
off_t MpgSnd_Decoder::ogrempg_lseek(void *user_data, off_t offset, int whence)
{
Ogre::DataStreamPtr stream = static_cast<MpgSnd_Decoder*>(user_data)->mDataStream;
if(whence == SEEK_CUR)
stream->seek(stream->tell()+offset);
else if(whence == SEEK_SET)
stream->seek(offset);
else if(whence == SEEK_END)
stream->seek(stream->size()+offset);
else
return -1;
return stream->tell();
}
void MpgSnd_Decoder::open(const std::string &fname)
{
close();
mDataStream = mResourceMgr.openResource(fname);
SF_VIRTUAL_IO streamIO = {
ogresf_get_filelen, ogresf_seek,
ogresf_read, ogresf_write, ogresf_tell
};
mSndFile = sf_open_virtual(&streamIO, SFM_READ, &mSndInfo, this);
if(mSndFile)
{
if(mSndInfo.channels == 1)
mChanConfig = ChannelConfig_Mono;
else if(mSndInfo.channels == 2)
mChanConfig = ChannelConfig_Stereo;
else
{
sf_close(mSndFile);
mSndFile = NULL;
fail("Unsupported channel count in "+fname);
}
mSampleRate = mSndInfo.samplerate;
return;
}
mDataStream->seek(0);
mMpgFile = mpg123_new(NULL, NULL);
if(mMpgFile && mpg123_replace_reader_handle(mMpgFile, ogrempg_read, ogrempg_lseek, NULL) == MPG123_OK &&
mpg123_open_handle(mMpgFile, this) == MPG123_OK)
{
try
{
int encoding, channels;
long rate;
if(mpg123_getformat(mMpgFile, &rate, &channels, &encoding) != MPG123_OK)
fail("Failed to get audio format");
if(encoding != MPG123_ENC_SIGNED_16)
fail("Unsupported encoding in "+fname);
if(channels != 1 && channels != 2)
fail("Unsupported channel count in "+fname);
mChanConfig = ((channels==2)?ChannelConfig_Stereo:ChannelConfig_Mono);
mSampleRate = rate;
return;
}
catch(std::exception &e)
{
mpg123_close(mMpgFile);
mpg123_delete(mMpgFile);
mMpgFile = NULL;
throw;
}
mpg123_close(mMpgFile);
}
if(mMpgFile)
mpg123_delete(mMpgFile);
mMpgFile = NULL;
fail("Unsupported file type: "+fname);
}
void MpgSnd_Decoder::close()
{
if(mSndFile)
sf_close(mSndFile);
mSndFile = NULL;
if(mMpgFile)
{
mpg123_close(mMpgFile);
mpg123_delete(mMpgFile);
mMpgFile = NULL;
}
mDataStream.setNull();
}
std::string MpgSnd_Decoder::getName()
{
return mDataStream->getName();
}
void MpgSnd_Decoder::getInfo(int *samplerate, ChannelConfig *chans, SampleType *type)
{
if(!mSndFile && !mMpgFile)
fail("No open file");
*samplerate = mSampleRate;
*chans = mChanConfig;
*type = SampleType_Int16;
}
size_t MpgSnd_Decoder::read(char *buffer, size_t bytes)
{
size_t got = 0;
if(mSndFile)
{
got = sf_read_short(mSndFile, (short*)buffer, bytes/2)*2;
}
else if(mMpgFile)
{
int err;
err = mpg123_read(mMpgFile, (unsigned char*)buffer, bytes, &got);
if(err != MPG123_OK && err != MPG123_DONE)
fail("Failed to read from file");
}
return got;
}
void MpgSnd_Decoder::readAll(std::vector<char> &output)
{
if(mSndFile && mSndInfo.frames > 0)
{
size_t pos = output.size();
output.resize(pos + mSndInfo.frames*mSndInfo.channels*2);
sf_readf_short(mSndFile, (short*)(&output[0]+pos), mSndInfo.frames);
return;
}
// Fallback in case we don't know the total already
Sound_Decoder::readAll(output);
}
void MpgSnd_Decoder::rewind()
{
if(!mSndFile && !mMpgFile)
fail("No open file");
if(mSndFile)
{
if(sf_seek(mSndFile, 0, SEEK_SET) == -1)
fail("seek failed");
}
else if(mMpgFile)
{
if(mpg123_seek(mMpgFile, 0, SEEK_SET) < 0)
fail("seek failed");
}
}
size_t MpgSnd_Decoder::getSampleOffset()
{
return 0;
}
MpgSnd_Decoder::MpgSnd_Decoder()
: mSndInfo()
, mSndFile(NULL)
, mMpgFile(NULL)
, mDataStream()
, mChanConfig(ChannelConfig_Stereo)
, mSampleRate(0)
{
static bool initdone = false;
if(!initdone)
mpg123_init();
initdone = true;
}
MpgSnd_Decoder::~MpgSnd_Decoder()
{
close();
}
}
#endif

View file

@ -1,59 +0,0 @@
#ifndef GAME_SOUND_MPGSND_DECODER_H
#define GAME_SOUND_MPGSND_DECODER_H
#include <string>
#include <OgreDataStream.h>
#include "mpg123.h"
#include "sndfile.h"
#include "sound_decoder.hpp"
namespace MWSound
{
class MpgSnd_Decoder : public Sound_Decoder
{
SF_INFO mSndInfo;
SNDFILE *mSndFile;
mpg123_handle *mMpgFile;
Ogre::DataStreamPtr mDataStream;
static sf_count_t ogresf_get_filelen(void *user_data);
static sf_count_t ogresf_seek(sf_count_t offset, int whence, void *user_data);
static sf_count_t ogresf_read(void *ptr, sf_count_t count, void *user_data);
static sf_count_t ogresf_write(const void*, sf_count_t, void*);
static sf_count_t ogresf_tell(void *user_data);
static ssize_t ogrempg_read(void*, void*, size_t);
static off_t ogrempg_lseek(void*, off_t, int);
ChannelConfig mChanConfig;
int mSampleRate;
virtual void open(const std::string &fname);
virtual void close();
virtual std::string getName();
virtual void getInfo(int *samplerate, ChannelConfig *chans, SampleType *type);
virtual size_t read(char *buffer, size_t bytes);
virtual void readAll(std::vector<char> &output);
virtual void rewind();
virtual size_t getSampleOffset();
MpgSnd_Decoder& operator=(const MpgSnd_Decoder &rhs);
MpgSnd_Decoder(const MpgSnd_Decoder &rhs);
MpgSnd_Decoder();
public:
virtual ~MpgSnd_Decoder();
friend class SoundManager;
};
#ifndef DEFAULT_DECODER
#define DEFAULT_DECODER (::MWSound::MpgSnd_Decoder)
#endif
}
#endif

View file

@ -17,8 +17,8 @@
#include "openal_output.hpp" #include "openal_output.hpp"
#define SOUND_OUT "OpenAL" #define SOUND_OUT "OpenAL"
/* Set up the sound manager to use FFMPEG, MPG123+libsndfile, or Audiere for /* Set up the sound manager to use FFMPEG for input.
* input. The OPENMW_USE_x macros are set in CMakeLists.txt. * The OPENMW_USE_x macros are set in CMakeLists.txt.
*/ */
#ifdef OPENMW_USE_FFMPEG #ifdef OPENMW_USE_FFMPEG
#include "ffmpeg_decoder.hpp" #include "ffmpeg_decoder.hpp"
@ -27,20 +27,6 @@
#endif #endif
#endif #endif
#ifdef OPENMW_USE_AUDIERE
#include "audiere_decoder.hpp"
#ifndef SOUND_IN
#define SOUND_IN "Audiere"
#endif
#endif
#ifdef OPENMW_USE_MPG123
#include "mpgsnd_decoder.hpp"
#ifndef SOUND_IN
#define SOUND_IN "mpg123,sndfile"
#endif
#endif
namespace MWSound namespace MWSound
{ {

View file

@ -201,7 +201,7 @@ void MWState::StateManager::saveGame (const std::string& description, const Slot
+MWBase::Environment::get().getWorld()->countSavedGameRecords() +MWBase::Environment::get().getWorld()->countSavedGameRecords()
+MWBase::Environment::get().getScriptManager()->getGlobalScripts().countSavedGameRecords() +MWBase::Environment::get().getScriptManager()->getGlobalScripts().countSavedGameRecords()
+MWBase::Environment::get().getDialogueManager()->countSavedGameRecords() +MWBase::Environment::get().getDialogueManager()->countSavedGameRecords()
+1; // global map +MWBase::Environment::get().getWindowManager()->countSavedGameRecords();
writer.setRecordCount (recordCount); writer.setRecordCount (recordCount);
writer.save (stream); writer.save (stream);
@ -235,8 +235,9 @@ void MWState::StateManager::saveGame (const std::string& description, const Slot
void MWState::StateManager::quickSave (std::string name) void MWState::StateManager::quickSave (std::string name)
{ {
if (mState!=State_Running || if (!(mState==State_Running &&
MWBase::Environment::get().getWorld()->getGlobalInt ("chargenstate")!=-1) // char gen MWBase::Environment::get().getWorld()->getGlobalInt ("chargenstate")==-1 // char gen
&& MWBase::Environment::get().getWindowManager()->isSavingAllowed()))
{ {
//You can not save your game right now //You can not save your game right now
MWBase::Environment::get().getWindowManager()->messageBox("#{sSaveGameDenied}"); MWBase::Environment::get().getWindowManager()->messageBox("#{sSaveGameDenied}");
@ -323,7 +324,7 @@ void MWState::StateManager::loadGame (const Character *character, const Slot *sl
break; break;
case ESM::REC_GMAP: case ESM::REC_GMAP:
case ESM::REC_KEYS:
MWBase::Environment::get().getWindowManager()->readRecord(reader, n.val); MWBase::Environment::get().getWindowManager()->readRecord(reader, n.val);
break; break;

View file

@ -231,6 +231,8 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add (const Ptr& itemPtr
{ {
CellStore *cell; CellStore *cell;
MWBase::Environment::get().getWorld()->getLocalScripts().add(script, item);
if(&(MWWorld::Class::get (player).getContainerStore (player)) == this) if(&(MWWorld::Class::get (player).getContainerStore (player)) == this)
{ {
cell = 0; // Items in player's inventory have cell set to 0, so their scripts will never be removed cell = 0; // Items in player's inventory have cell set to 0, so their scripts will never be removed
@ -243,7 +245,6 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add (const Ptr& itemPtr
item.mCell = cell; item.mCell = cell;
item.mContainerStore = 0; item.mContainerStore = 0;
MWBase::Environment::get().getWorld()->getLocalScripts().add(script, item);
} }
return it; return it;

View file

@ -227,10 +227,6 @@ namespace MWWorld
Ogre::Vector3 inertia(0.0f); Ogre::Vector3 inertia(0.0f);
Ogre::Vector3 velocity; Ogre::Vector3 velocity;
bool canWalk = ptr.getClass().canWalk(ptr);
bool isBipedal = ptr.getClass().isBipedal(ptr);
bool isNpc = ptr.getClass().isNpc();
if(position.z < waterlevel || isFlying) // under water by 3/4 or can fly if(position.z < waterlevel || isFlying) // under water by 3/4 or can fly
{ {
// TODO: Shouldn't water have higher drag in calculating velocity? // TODO: Shouldn't water have higher drag in calculating velocity?
@ -286,14 +282,11 @@ namespace MWWorld
// NOTE: velocity is either z axis only or x & z axis // NOTE: velocity is either z axis only or x & z axis
Ogre::Vector3 nextpos = newPosition + velocity * remainingTime; Ogre::Vector3 nextpos = newPosition + velocity * remainingTime;
// If not able to fly, walk or bipedal don't allow to move out of water // If not able to fly, don't allow to swim up into the air
// TODO: this if condition may not work for large creatures or situations // TODO: this if condition may not work for large creatures or situations
// where the creature gets above the waterline for some reason // where the creature gets above the waterline for some reason
if(newPosition.z < waterlevel && // started 3/4 under water if(newPosition.z < waterlevel && // started 3/4 under water
!isFlying && // can't fly !isFlying && // can't fly
!canWalk && // can't walk
!isBipedal && // not bipedal (assume bipedals can walk)
!isNpc && // FIXME: shouldn't really need this
nextpos.z > waterlevel && // but about to go above water nextpos.z > waterlevel && // but about to go above water
newPosition.z <= waterlevel) newPosition.z <= waterlevel)
{ {

View file

@ -37,7 +37,7 @@ namespace MWWorld
mTeleported(false), mTeleported(false),
mMarkedCell(NULL), mMarkedCell(NULL),
mCurrentCrimeId(-1), mCurrentCrimeId(-1),
mPayedCrimeId(-1) mPaidCrimeId(-1)
{ {
mPlayer.mBase = player; mPlayer.mBase = player;
mPlayer.mRef.mRefID = "player"; mPlayer.mRef.mRefID = "player";
@ -100,7 +100,6 @@ namespace MWWorld
void Player::setLeftRight (int value) void Player::setLeftRight (int value)
{ {
MWWorld::Ptr ptr = getPlayer(); MWWorld::Ptr ptr = getPlayer();
MWWorld::Class::get (ptr).getMovementSettings (ptr).mPosition[0] = value; MWWorld::Class::get (ptr).getMovementSettings (ptr).mPosition[0] = value;
} }
@ -119,7 +118,6 @@ namespace MWWorld
void Player::setUpDown(int value) void Player::setUpDown(int value)
{ {
MWWorld::Ptr ptr = getPlayer(); MWWorld::Ptr ptr = getPlayer();
MWWorld::Class::get (ptr).getMovementSettings (ptr).mPosition[2] = value; MWWorld::Class::get (ptr).getMovementSettings (ptr).mPosition[2] = value;
} }
@ -132,28 +130,10 @@ namespace MWWorld
void Player::setSneak(bool sneak) void Player::setSneak(bool sneak)
{ {
MWWorld::Ptr ptr = getPlayer(); MWWorld::Ptr ptr = getPlayer();
ptr.getClass().getCreatureStats(ptr).setMovementFlag(MWMechanics::CreatureStats::Flag_Sneak, sneak); ptr.getClass().getCreatureStats(ptr).setMovementFlag(MWMechanics::CreatureStats::Flag_Sneak, sneak);
if (sneak == true) if(!sneak)
{ MWBase::Environment::get().getWindowManager()->setSneakVisibility(false);
const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore();
// Find all the actors who might be able to see the player
std::vector<MWWorld::Ptr> neighbors;
MWBase::Environment::get().getMechanicsManager()->getActorsInRange( Ogre::Vector3(ptr.getRefData().getPosition().pos),
esmStore.get<ESM::GameSetting>().find("fSneakUseDist")->getInt(), neighbors);
for (std::vector<MWWorld::Ptr>::iterator it = neighbors.begin(); it != neighbors.end(); ++it)
{
if ( MWBase::Environment::get().getMechanicsManager()->awarenessCheck(ptr, *it) )
{
MWBase::Environment::get().getWindowManager()->setSneakVisibility(false);
break;
}
}
if (neighbors.empty())
MWBase::Environment::get().getWindowManager()->setSneakVisibility(true);
}
} }
void Player::yaw(float yaw) void Player::yaw(float yaw)
@ -223,7 +203,7 @@ namespace MWWorld
player.mCellId = mCellStore->getCell()->getCellId(); player.mCellId = mCellStore->getCell()->getCellId();
player.mCurrentCrimeId = mCurrentCrimeId; player.mCurrentCrimeId = mCurrentCrimeId;
player.mPayedCrimeId = mPayedCrimeId; player.mPaidCrimeId = mPaidCrimeId;
player.mBirthsign = mSign; player.mBirthsign = mSign;
@ -273,7 +253,7 @@ namespace MWWorld
throw std::runtime_error ("invalid player state record (birthsign)"); throw std::runtime_error ("invalid player state record (birthsign)");
mCurrentCrimeId = player.mCurrentCrimeId; mCurrentCrimeId = player.mCurrentCrimeId;
mPayedCrimeId = player.mPayedCrimeId; mPaidCrimeId = player.mPaidCrimeId;
mSign = player.mBirthsign; mSign = player.mBirthsign;
@ -318,11 +298,11 @@ namespace MWWorld
void Player::recordCrimeId() void Player::recordCrimeId()
{ {
mPayedCrimeId = mCurrentCrimeId; mPaidCrimeId = mCurrentCrimeId;
} }
int Player::getCrimeId() const int Player::getCrimeId() const
{ {
return mPayedCrimeId; return mPaidCrimeId;
} }
} }

View file

@ -48,7 +48,7 @@ namespace MWWorld
bool mTeleported; bool mTeleported;
int mCurrentCrimeId; // the id assigned witnesses int mCurrentCrimeId; // the id assigned witnesses
int mPayedCrimeId; // the last id payed off (0 bounty) int mPaidCrimeId; // the last id paid off (0 bounty)
public: public:
@ -105,8 +105,8 @@ namespace MWWorld
bool readRecord (ESM::ESMReader& reader, int32_t type); bool readRecord (ESM::ESMReader& reader, int32_t type);
int getNewCrimeId(); // get new id for witnesses int getNewCrimeId(); // get new id for witnesses
void recordCrimeId(); // record the payed crime id when bounty is 0 void recordCrimeId(); // record the paid crime id when bounty is 0
int getCrimeId() const; // get the last payed crime id int getCrimeId() const; // get the last paid crime id
}; };
} }
#endif #endif

View file

@ -329,7 +329,6 @@ void WeatherManager::update(float duration)
const bool exterior = (world->isCellExterior() || world->isCellQuasiExterior()); const bool exterior = (world->isCellExterior() || world->isCellQuasiExterior());
if (!exterior) if (!exterior)
{ {
mRendering->sunDisable(false);
mRendering->skyDisable(); mRendering->skyDisable();
mRendering->getSkyManager()->setLightningStrength(0.f); mRendering->getSkyManager()->setLightningStrength(0.f);
stopSounds(true); stopSounds(true);

View file

@ -1,60 +0,0 @@
# Locate Audiere
# This module defines
# AUDIERE_LIBRARY
# AUDIERE_FOUND, if false, do not try to link to Audiere
# AUDIERE_INCLUDE_DIR, where to find the headers
#
# Created by Nicolay Korslund for OpenMW (http://openmw.com)
#
# More or less a direct ripoff of FindOpenAL.cmake by Eric Wing.
#=============================================================================
# Copyright 2005-2009 Kitware, Inc.
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distributed this file outside of CMake, substitute the full
# License text for the above reference.)
FIND_PATH(AUDIERE_INCLUDE_DIR audiere.h
HINTS
PATH_SUFFIXES include
PATHS
$ENV{AUDIERE_DIR}
~/Library/Frameworks
/Library/Frameworks
/usr/local
/usr
/sw # Fink
/opt/local # DarwinPorts
/opt/csw # Blastwave
/opt
)
FIND_LIBRARY(AUDIERE_LIBRARY
NAMES audiere
HINTS
PATH_SUFFIXES lib64 lib libs64 libs libs/Win32 libs/Win64
PATHS
$ENV{AUDIERE_DIR}
~/Library/Frameworks
/Library/Frameworks
/usr/local
/usr
/sw
/opt/local
/opt/csw
/opt
)
SET(AUDIERE_FOUND "NO")
IF(AUDIERE_LIBRARY AND AUDIERE_INCLUDE_DIR)
SET(AUDIERE_FOUND "YES")
ENDIF(AUDIERE_LIBRARY AND AUDIERE_INCLUDE_DIR)

View file

@ -1,47 +0,0 @@
# Locate MPG123
# This module defines
# MPG123_LIBRARY
# MPG123_FOUND, if false, do not try to link to Mpg123
# MPG123_INCLUDE_DIR, where to find the headers
#
# Created by Nicolay Korslund for OpenMW (http://openmw.com)
#
# Ripped off from other sources. In fact, this file is so generic (I
# just did a search and replace on another file) that I wonder why the
# CMake guys haven't wrapped this entire thing in a single
# function. Do we really need to repeat this stuff for every single
# library when they all work the same? </today's rant>
FIND_PATH(MPG123_INCLUDE_DIR mpg123.h
HINTS
PATHS
~/Library/Frameworks
/Library/Frameworks
/usr/local
/usr
/sw # Fink
/opt/local # DarwinPorts
/opt/csw # Blastwave
/opt
)
FIND_LIBRARY(MPG123_LIBRARY
NAMES mpg123
HINTS
PATH_SUFFIXES lib64 lib libs64 libs libs/Win32 libs/Win64
PATHS
~/Library/Frameworks
/Library/Frameworks
/usr/local
/usr
/sw
/opt/local
/opt/csw
/opt
)
SET(MPG123_FOUND "NO")
IF(MPG123_LIBRARY AND MPG123_INCLUDE_DIR)
SET(MPG123_FOUND "YES")
ENDIF(MPG123_LIBRARY AND MPG123_INCLUDE_DIR)

View file

@ -1,41 +0,0 @@
# Locate SNDFILE
# This module defines
# SNDFILE_LIBRARY
# SNDFILE_FOUND, if false, do not try to link to Sndfile
# SNDFILE_INCLUDE_DIR, where to find the headers
#
# Created by Nicolay Korslund for OpenMW (http://openmw.com)
FIND_PATH(SNDFILE_INCLUDE_DIR sndfile.h
HINTS
PATHS
~/Library/Frameworks
/Library/Frameworks
/usr/local
/usr
/sw # Fink
/opt/local # DarwinPorts
/opt/csw # Blastwave
/opt
)
FIND_LIBRARY(SNDFILE_LIBRARY
NAMES sndfile
HINTS
PATH_SUFFIXES lib64 lib libs64 libs libs/Win32 libs/Win64
PATHS
~/Library/Frameworks
/Library/Frameworks
/usr/local
/usr
/sw
/opt/local
/opt/csw
/opt
)
SET(SNDFILE_FOUND "NO")
IF(SNDFILE_LIBRARY AND SNDFILE_INCLUDE_DIR)
SET(SNDFILE_FOUND "YES")
ENDIF(SNDFILE_LIBRARY AND SNDFILE_INCLUDE_DIR)

View file

@ -45,7 +45,7 @@ add_component_dir (esm
loadnpc loadpgrd loadrace loadregn loadscpt loadskil loadsndg loadsoun loadspel loadsscr loadstat loadnpc loadpgrd loadrace loadregn loadscpt loadskil loadsndg loadsoun loadspel loadsscr loadstat
loadweap records aipackage effectlist spelllist variant variantimp loadtes3 cellref filter loadweap records aipackage effectlist spelllist variant variantimp loadtes3 cellref filter
savedgame journalentry queststate locals globalscript player objectstate cellid cellstate globalmap lightstate inventorystate containerstate npcstate creaturestate dialoguestate statstate savedgame journalentry queststate locals globalscript player objectstate cellid cellstate globalmap lightstate inventorystate containerstate npcstate creaturestate dialoguestate statstate
npcstats creaturestats weatherstate npcstats creaturestats weatherstate quickkeys
) )
add_component_dir (misc add_component_dir (misc

View file

@ -34,6 +34,12 @@ struct Position
}; };
#pragma pack(pop) #pragma pack(pop)
template <int a, int b, int c, int d>
struct FourCC
{
static const unsigned int value = (((((d << 8) | c) << 8) | b) << 8) | a;
};
enum RecNameInts enum RecNameInts
{ {
// format 0 / legacy // format 0 / legacy
@ -93,6 +99,7 @@ enum RecNameInts
REC_GMAP = 0x50414d47, REC_GMAP = 0x50414d47,
REC_DIAS = 0x53414944, REC_DIAS = 0x53414944,
REC_WTHR = 0x52485457, REC_WTHR = 0x52485457,
REC_KEYS = FourCC<'K','E','Y','S'>::value,
// format 1 // format 1
REC_FILT = 0x544C4946 REC_FILT = 0x544C4946

View file

@ -33,7 +33,7 @@ struct Creature
Respawn = 0x002, Respawn = 0x002,
Weapon = 0x004, // Has weapon and shield Weapon = 0x004, // Has weapon and shield
None = 0x008, // ?? None = 0x008, // ?? This flag appears set for every creature in Morrowind.esm
Essential = 0x080, Essential = 0x080,
// Blood types // Blood types

View file

@ -28,8 +28,8 @@ void ESM::Player::load (ESMReader &esm)
mCurrentCrimeId = -1; mCurrentCrimeId = -1;
esm.getHNOT (mCurrentCrimeId, "CURD"); esm.getHNOT (mCurrentCrimeId, "CURD");
mPayedCrimeId = -1; mPaidCrimeId = -1;
esm.getHNOT (mPayedCrimeId, "PAYD"); esm.getHNOT (mPaidCrimeId, "PAYD");
} }
void ESM::Player::save (ESMWriter &esm) const void ESM::Player::save (ESMWriter &esm) const
@ -52,5 +52,5 @@ void ESM::Player::save (ESMWriter &esm) const
esm.writeHNString ("SIGN", mBirthsign); esm.writeHNString ("SIGN", mBirthsign);
esm.writeHNT ("CURD", mCurrentCrimeId); esm.writeHNT ("CURD", mCurrentCrimeId);
esm.writeHNT ("PAYD", mPayedCrimeId); esm.writeHNT ("PAYD", mPaidCrimeId);
} }

View file

@ -26,11 +26,11 @@ namespace ESM
std::string mBirthsign; std::string mBirthsign;
int mCurrentCrimeId; int mCurrentCrimeId;
int mPayedCrimeId; int mPaidCrimeId;
void load (ESMReader &esm); void load (ESMReader &esm);
void save (ESMWriter &esm) const; void save (ESMWriter &esm) const;
}; };
} }
#endif #endif

View file

@ -0,0 +1,43 @@
#include "quickkeys.hpp"
#include "esmwriter.hpp"
#include "esmreader.hpp"
namespace ESM
{
void QuickKeys::load(ESMReader &esm)
{
while (esm.isNextSub("KEY_"))
{
esm.getSubHeader();
int keyType;
esm.getHNT(keyType, "TYPE");
std::string id;
id = esm.getHNString("ID__");
QuickKey key;
key.mType = keyType;
key.mId = id;
mKeys.push_back(key);
}
}
void QuickKeys::save(ESMWriter &esm) const
{
const std::string recKey = "KEY_";
for (std::vector<QuickKey>::const_iterator it = mKeys.begin(); it != mKeys.end(); ++it)
{
esm.startSubRecord(recKey);
esm.writeHNT("TYPE", it->mType);
esm.writeHNString("ID__", it->mId);
esm.endRecord(recKey);
}
}
}

View file

@ -0,0 +1,28 @@
#ifndef OPENMW_COMPONENTS_ESM_QUICKKEYS_H
#define OPENMW_COMPONENTS_ESM_QUICKKEYS_H
#include <vector>
#include <string>
namespace ESM
{
class ESMReader;
class ESMWriter;
struct QuickKeys
{
struct QuickKey
{
int mType;
std::string mId; // Spell or Item ID
};
std::vector<QuickKey> mKeys;
void load (ESMReader &esm);
void save (ESMWriter &esm) const;
};
}
#endif

View file

@ -62,6 +62,7 @@ namespace OgreInit
OgreInit::~OgreInit() OgreInit::~OgreInit()
{ {
delete mRoot; delete mRoot;
delete Ogre::LogManager::getSingletonPtr();
std::vector<Ogre::ParticleEmitterFactory*>::iterator ei; std::vector<Ogre::ParticleEmitterFactory*>::iterator ei;
for(ei = mEmitterFactories.begin();ei != mEmitterFactories.end();++ei) for(ei = mEmitterFactories.begin();ei != mEmitterFactories.end();++ei)

View file

@ -337,6 +337,8 @@ namespace Terrain
it->mTarget->loadLayers(*it); it->mTarget->loadLayers(*it);
} }
delete data;
mRootNode->loadMaterials(); mRootNode->loadMaterials();
mLayerLoadPending = false; mLayerLoadPending = false;

View file

@ -115,7 +115,7 @@ namespace SFO
mWindowListener->windowClosed(); mWindowListener->windowClosed();
break; break;
default: default:
std::cerr << "Unhandled SDL event of type " << evt.type << std::endl; std::cerr << "Unhandled SDL event of type 0x" << std::hex << evt.type << std::endl;
break; break;
} }
} }
@ -241,8 +241,8 @@ namespace SFO
//eep, wrap the pointer manually if the input driver doesn't support //eep, wrap the pointer manually if the input driver doesn't support
//relative positioning natively //relative positioning natively
int success = SDL_SetRelativeMouseMode(relative ? SDL_TRUE : SDL_FALSE); bool success = SDL_SetRelativeMouseMode(relative ? SDL_TRUE : SDL_FALSE) == 0;
if(relative && success != 0) if(relative && !success)
mWrapPointer = true; mWrapPointer = true;
//now remove all mouse events using the old setting from the queue //now remove all mouse events using the old setting from the queue

View file

@ -49,22 +49,6 @@
<BasisSkin type="SimpleText" offset="0 0 16 16" align="Stretch"/> <BasisSkin type="SimpleText" offset="0 0 16 16" align="Stretch"/>
</Skin> </Skin>
<Skin name="DaedricText" size="16 16">
<Property key="FontName" value="daedric36"/>
<Property key="FontHeight" value="36"/>
<Property key="TextAlign" value="Default"/>
<Property key="TextColour" value="1 1 1"/>
<BasisSkin type="SimpleText" offset="0 0 16 16" align="Stretch"/>
</Skin>
<Skin name="DaedricText_orig" size="16 16">
<Property key="FontName" value="daedric_orig36"/>
<Property key="FontHeight" value="36"/>
<Property key="TextAlign" value="Default"/>
<Property key="TextColour" value="1 1 1"/>
<BasisSkin type="SimpleText" offset="0 0 16 16" align="Stretch"/>
</Skin>
<Skin name="MW_StatNameC" size="200 18"> <Skin name="MW_StatNameC" size="200 18">
<Child type="TextBoxC" skin="SandText" offset="0 0 200 18" align="Left HStretch" name="StatName"/> <Child type="TextBoxC" skin="SandText" offset="0 0 200 18" align="Left HStretch" name="StatName"/>
</Skin> </Skin>

View file

@ -133,9 +133,9 @@ distant land = false
shader = true shader = true
[Water] [Water]
shader = true shader = false
refraction = true refraction = false
rtt size = 512 rtt size = 512
reflect terrain = true reflect terrain = true