forked from mirror/openmw-tes3mp
commit
7a38a0b223
@ -1,28 +1,341 @@
|
|||||||
#include "columnimp.hpp"
|
#include "columnimp.hpp"
|
||||||
|
|
||||||
CSMWorld::BodyPartRaceColumn::BodyPartRaceColumn(const MeshTypeColumn<ESM::BodyPart> *meshType)
|
#include <stdexcept>
|
||||||
: mMeshType(meshType)
|
#include <QVector>
|
||||||
{}
|
|
||||||
|
|
||||||
QVariant CSMWorld::BodyPartRaceColumn::get(const Record<ESM::BodyPart> &record) const
|
namespace CSMWorld
|
||||||
{
|
{
|
||||||
if (mMeshType != NULL && mMeshType->get(record) == ESM::BodyPart::MT_Skin)
|
/* LandTextureNicknameColumn */
|
||||||
|
LandTextureNicknameColumn::LandTextureNicknameColumn()
|
||||||
|
: Column<LandTexture>(Columns::ColumnId_TextureNickname, ColumnBase::Display_String)
|
||||||
{
|
{
|
||||||
return QString::fromUtf8(record.get().mRace.c_str());
|
|
||||||
}
|
}
|
||||||
return QVariant(QVariant::UserType);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSMWorld::BodyPartRaceColumn::set(Record<ESM::BodyPart> &record, const QVariant &data)
|
QVariant LandTextureNicknameColumn::get(const Record<LandTexture>& record) const
|
||||||
{
|
{
|
||||||
ESM::BodyPart record2 = record.get();
|
return QString::fromUtf8(record.get().mId.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
record2.mRace = data.toString().toUtf8().constData();
|
void LandTextureNicknameColumn::set(Record<LandTexture>& record, const QVariant& data)
|
||||||
|
{
|
||||||
|
LandTexture copy = record.get();
|
||||||
|
copy.mId = data.toString().toUtf8().constData();
|
||||||
|
record.setModified(copy);
|
||||||
|
}
|
||||||
|
|
||||||
record.setModified(record2);
|
bool LandTextureNicknameColumn::isEditable() const
|
||||||
}
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool CSMWorld::BodyPartRaceColumn::isEditable() const
|
/* LandTextureIndexColumn */
|
||||||
{
|
LandTextureIndexColumn::LandTextureIndexColumn()
|
||||||
return true;
|
: Column<LandTexture>(Columns::ColumnId_TextureIndex, ColumnBase::Display_Integer)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant LandTextureIndexColumn::get(const Record<LandTexture>& record) const
|
||||||
|
{
|
||||||
|
return record.get().mIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LandTextureIndexColumn::isEditable() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* LandPluginIndexColumn */
|
||||||
|
LandPluginIndexColumn::LandPluginIndexColumn()
|
||||||
|
: Column<Land>(Columns::ColumnId_PluginIndex, ColumnBase::Display_Integer, 0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant LandPluginIndexColumn::get(const Record<Land>& record) const
|
||||||
|
{
|
||||||
|
return record.get().mPlugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LandPluginIndexColumn::isEditable() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* LandTexturePluginIndexColumn */
|
||||||
|
LandTexturePluginIndexColumn::LandTexturePluginIndexColumn()
|
||||||
|
: Column<LandTexture>(Columns::ColumnId_PluginIndex, ColumnBase::Display_Integer, 0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant LandTexturePluginIndexColumn::get(const Record<LandTexture>& record) const
|
||||||
|
{
|
||||||
|
return record.get().mPluginIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LandTexturePluginIndexColumn::isEditable() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* LandMapLodColumn */
|
||||||
|
LandMapLodColumn::LandMapLodColumn()
|
||||||
|
: Column<Land>(Columns::ColumnId_LandMapLodIndex, ColumnBase::Display_String, 0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant LandMapLodColumn::get(const Record<Land>& record) const
|
||||||
|
{
|
||||||
|
const int Size = Land::LAND_GLOBAL_MAP_LOD_SIZE;
|
||||||
|
const Land& land = record.get();
|
||||||
|
|
||||||
|
DataType values(Size, 0);
|
||||||
|
|
||||||
|
if (land.isDataLoaded(Land::DATA_WNAM))
|
||||||
|
{
|
||||||
|
for (int i = 0; i < Size; ++i)
|
||||||
|
values[i] = land.mWnam[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant variant;
|
||||||
|
variant.setValue(values);
|
||||||
|
return variant;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandMapLodColumn::set(Record<Land>& record, const QVariant& data)
|
||||||
|
{
|
||||||
|
DataType values = data.value<DataType>();
|
||||||
|
|
||||||
|
if (values.size() != Land::LAND_GLOBAL_MAP_LOD_SIZE)
|
||||||
|
throw std::runtime_error("invalid land map LOD data");
|
||||||
|
|
||||||
|
Land copy = record.get();
|
||||||
|
copy.setDataLoaded(Land::DATA_WNAM);
|
||||||
|
|
||||||
|
for (int i = 0; i < values.size(); ++i)
|
||||||
|
{
|
||||||
|
copy.mWnam[i] = values[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
record.setModified(copy);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LandMapLodColumn::isEditable() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* LandNormalsColumn */
|
||||||
|
LandNormalsColumn::LandNormalsColumn()
|
||||||
|
: Column<Land>(Columns::ColumnId_LandNormalsIndex, ColumnBase::Display_String, 0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant LandNormalsColumn::get(const Record<Land>& record) const
|
||||||
|
{
|
||||||
|
const int Size = Land::LAND_NUM_VERTS * 3;
|
||||||
|
const Land& land = record.get();
|
||||||
|
|
||||||
|
DataType values(Size, 0);
|
||||||
|
|
||||||
|
if (land.isDataLoaded(Land::DATA_VNML))
|
||||||
|
{
|
||||||
|
for (int i = 0; i < Size; ++i)
|
||||||
|
values[i] = land.getLandData()->mNormals[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant variant;
|
||||||
|
variant.setValue(values);
|
||||||
|
return variant;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandNormalsColumn::set(Record<Land>& record, const QVariant& data)
|
||||||
|
{
|
||||||
|
DataType values = data.value<DataType>();
|
||||||
|
|
||||||
|
if (values.size() != Land::LAND_NUM_VERTS * 3)
|
||||||
|
throw std::runtime_error("invalid land normals data");
|
||||||
|
|
||||||
|
Land copy = record.get();
|
||||||
|
copy.setDataLoaded(Land::DATA_VNML);
|
||||||
|
|
||||||
|
for (int i = 0; i < values.size(); ++i)
|
||||||
|
{
|
||||||
|
copy.getLandData()->mNormals[i] = values[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
record.setModified(copy);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LandNormalsColumn::isEditable() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* LandHeightsColumn */
|
||||||
|
LandHeightsColumn::LandHeightsColumn()
|
||||||
|
: Column<Land>(Columns::ColumnId_LandHeightsIndex, ColumnBase::Display_String, 0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant LandHeightsColumn::get(const Record<Land>& record) const
|
||||||
|
{
|
||||||
|
const int Size = Land::LAND_NUM_VERTS;
|
||||||
|
const Land& land = record.get();
|
||||||
|
|
||||||
|
DataType values(Size, 0);
|
||||||
|
|
||||||
|
if (land.isDataLoaded(Land::DATA_VHGT))
|
||||||
|
{
|
||||||
|
for (int i = 0; i < Size; ++i)
|
||||||
|
values[i] = land.getLandData()->mHeights[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant variant;
|
||||||
|
variant.setValue(values);
|
||||||
|
return variant;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandHeightsColumn::set(Record<Land>& record, const QVariant& data)
|
||||||
|
{
|
||||||
|
DataType values = data.value<DataType>();
|
||||||
|
|
||||||
|
if (values.size() != Land::LAND_NUM_VERTS)
|
||||||
|
throw std::runtime_error("invalid land heights data");
|
||||||
|
|
||||||
|
Land copy = record.get();
|
||||||
|
copy.setDataLoaded(Land::DATA_VHGT);
|
||||||
|
|
||||||
|
for (int i = 0; i < values.size(); ++i)
|
||||||
|
{
|
||||||
|
copy.getLandData()->mHeights[i] = values[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
record.setModified(copy);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LandHeightsColumn::isEditable() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* LandColoursColumn */
|
||||||
|
LandColoursColumn::LandColoursColumn()
|
||||||
|
: Column<Land>(Columns::ColumnId_LandColoursIndex, ColumnBase::Display_String, 0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant LandColoursColumn::get(const Record<Land>& record) const
|
||||||
|
{
|
||||||
|
const int Size = Land::LAND_NUM_VERTS * 3;
|
||||||
|
const Land& land = record.get();
|
||||||
|
|
||||||
|
DataType values(Size, 0);
|
||||||
|
|
||||||
|
if (land.isDataLoaded(Land::DATA_VCLR))
|
||||||
|
{
|
||||||
|
for (int i = 0; i < Size; ++i)
|
||||||
|
values[i] = land.getLandData()->mColours[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant variant;
|
||||||
|
variant.setValue(values);
|
||||||
|
return variant;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandColoursColumn::set(Record<Land>& record, const QVariant& data)
|
||||||
|
{
|
||||||
|
DataType values = data.value<DataType>();
|
||||||
|
|
||||||
|
if (values.size() != Land::LAND_NUM_VERTS * 3)
|
||||||
|
throw std::runtime_error("invalid land colours data");
|
||||||
|
|
||||||
|
Land copy = record.get();
|
||||||
|
copy.setDataLoaded(Land::DATA_VCLR);
|
||||||
|
|
||||||
|
for (int i = 0; i < values.size(); ++i)
|
||||||
|
{
|
||||||
|
copy.getLandData()->mColours[i] = values[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
record.setModified(copy);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LandColoursColumn::isEditable() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* LandTexturesColumn */
|
||||||
|
LandTexturesColumn::LandTexturesColumn()
|
||||||
|
: Column<Land>(Columns::ColumnId_LandTexturesIndex, ColumnBase::Display_String, 0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant LandTexturesColumn::get(const Record<Land>& record) const
|
||||||
|
{
|
||||||
|
const int Size = Land::LAND_NUM_TEXTURES;
|
||||||
|
const Land& land = record.get();
|
||||||
|
|
||||||
|
DataType values(Size, 0);
|
||||||
|
|
||||||
|
if (land.isDataLoaded(Land::DATA_VTEX))
|
||||||
|
{
|
||||||
|
for (int i = 0; i < Size; ++i)
|
||||||
|
values[i] = land.getLandData()->mTextures[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant variant;
|
||||||
|
variant.setValue(values);
|
||||||
|
return variant;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandTexturesColumn::set(Record<Land>& record, const QVariant& data)
|
||||||
|
{
|
||||||
|
DataType values = data.value<DataType>();
|
||||||
|
|
||||||
|
if (values.size() != Land::LAND_NUM_TEXTURES)
|
||||||
|
throw std::runtime_error("invalid land textures data");
|
||||||
|
|
||||||
|
Land copy = record.get();
|
||||||
|
copy.setDataLoaded(Land::DATA_VTEX);
|
||||||
|
|
||||||
|
for (int i = 0; i < values.size(); ++i)
|
||||||
|
{
|
||||||
|
copy.getLandData()->mTextures[i] = values[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
record.setModified(copy);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LandTexturesColumn::isEditable() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* BodyPartRaceColumn */
|
||||||
|
BodyPartRaceColumn::BodyPartRaceColumn(const MeshTypeColumn<ESM::BodyPart> *meshType)
|
||||||
|
: mMeshType(meshType)
|
||||||
|
{}
|
||||||
|
|
||||||
|
QVariant BodyPartRaceColumn::get(const Record<ESM::BodyPart> &record) const
|
||||||
|
{
|
||||||
|
if (mMeshType != NULL && mMeshType->get(record) == ESM::BodyPart::MT_Skin)
|
||||||
|
{
|
||||||
|
return QString::fromUtf8(record.get().mRace.c_str());
|
||||||
|
}
|
||||||
|
return QVariant(QVariant::UserType);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BodyPartRaceColumn::set(Record<ESM::BodyPart> &record, const QVariant &data)
|
||||||
|
{
|
||||||
|
ESM::BodyPart record2 = record.get();
|
||||||
|
|
||||||
|
record2.mRace = data.toString().toUtf8().constData();
|
||||||
|
|
||||||
|
record.setModified(record2);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BodyPartRaceColumn::isEditable() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,30 @@
|
|||||||
#include "land.hpp"
|
#include "land.hpp"
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
namespace CSMWorld
|
namespace CSMWorld
|
||||||
{
|
{
|
||||||
void Land::load(ESM::ESMReader &esm, bool &isDeleted)
|
void Land::load(ESM::ESMReader &esm, bool &isDeleted)
|
||||||
{
|
{
|
||||||
ESM::Land::load(esm, isDeleted);
|
ESM::Land::load(esm, isDeleted);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Land::createUniqueRecordId(int x, int y)
|
||||||
|
{
|
||||||
std::ostringstream stream;
|
std::ostringstream stream;
|
||||||
stream << "#" << mX << " " << mY;
|
stream << "#" << x << " " << y;
|
||||||
mId = stream.str();
|
return stream.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Land::parseUniqueRecordId(const std::string& id, int& x, int& y)
|
||||||
|
{
|
||||||
|
size_t mid = id.find(' ');
|
||||||
|
|
||||||
|
if (mid == std::string::npos || id[0] != '#')
|
||||||
|
throw std::runtime_error("Invalid Land ID");
|
||||||
|
|
||||||
|
x = std::stoi(id.substr(1, mid - 1));
|
||||||
|
y = std::stoi(id.substr(mid + 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,21 @@
|
|||||||
|
#include "landtexturetableproxymodel.hpp"
|
||||||
|
|
||||||
|
#include "idtable.hpp"
|
||||||
|
|
||||||
|
namespace CSMWorld
|
||||||
|
{
|
||||||
|
LandTextureTableProxyModel::LandTextureTableProxyModel(QObject* parent)
|
||||||
|
: IdTableProxyModel(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LandTextureTableProxyModel::filterAcceptsRow (int sourceRow, const QModelIndex& sourceParent) const
|
||||||
|
{
|
||||||
|
int columnIndex = mSourceModel->findColumnIndex(Columns::ColumnId_Modification);
|
||||||
|
QModelIndex index = mSourceModel->index(sourceRow, columnIndex);
|
||||||
|
if (mSourceModel->data(index).toInt() != RecordBase::State_ModifiedOnly)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return IdTableProxyModel::filterAcceptsRow(sourceRow, sourceParent);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
#ifndef CSM_WORLD_LANDTEXTURETABLEPROXYMODEL_H
|
||||||
|
#define CSM_WORLD_LANDTEXTURETABLEPROXYMODEL_H
|
||||||
|
|
||||||
|
#include "idtableproxymodel.hpp"
|
||||||
|
|
||||||
|
namespace CSMWorld
|
||||||
|
{
|
||||||
|
/// \brief Removes base records from filtered results.
|
||||||
|
class LandTextureTableProxyModel : public IdTableProxyModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
|
||||||
|
LandTextureTableProxyModel(QObject* parent = nullptr);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
bool filterAcceptsRow (int sourceRow, const QModelIndex& sourceParent) const override;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,120 @@
|
|||||||
|
#include "landcreator.hpp"
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QSpinBox>
|
||||||
|
|
||||||
|
#include "../../model/world/commands.hpp"
|
||||||
|
#include "../../model/world/idtable.hpp"
|
||||||
|
#include "../../model/world/land.hpp"
|
||||||
|
|
||||||
|
namespace CSVWorld
|
||||||
|
{
|
||||||
|
LandCreator::LandCreator(CSMWorld::Data& data, QUndoStack& undoStack, const CSMWorld::UniversalId& id)
|
||||||
|
: GenericCreator(data, undoStack, id)
|
||||||
|
, mXLabel(nullptr)
|
||||||
|
, mYLabel(nullptr)
|
||||||
|
, mX(nullptr)
|
||||||
|
, mY(nullptr)
|
||||||
|
{
|
||||||
|
const int MaxInt = std::numeric_limits<int>::max();
|
||||||
|
const int MinInt = std::numeric_limits<int>::min();
|
||||||
|
|
||||||
|
setManualEditing(false);
|
||||||
|
|
||||||
|
mXLabel = new QLabel("X: ");
|
||||||
|
mX = new QSpinBox();
|
||||||
|
mX->setMinimum(MinInt);
|
||||||
|
mX->setMaximum(MaxInt);
|
||||||
|
insertBeforeButtons(mXLabel, false);
|
||||||
|
insertBeforeButtons(mX, true);
|
||||||
|
|
||||||
|
mYLabel = new QLabel("Y: ");
|
||||||
|
mY = new QSpinBox();
|
||||||
|
mY->setMinimum(MinInt);
|
||||||
|
mY->setMaximum(MaxInt);
|
||||||
|
insertBeforeButtons(mYLabel, false);
|
||||||
|
insertBeforeButtons(mY, true);
|
||||||
|
|
||||||
|
connect (mX, SIGNAL(valueChanged(int)), this, SLOT(coordChanged(int)));
|
||||||
|
connect (mY, SIGNAL(valueChanged(int)), this, SLOT(coordChanged(int)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandCreator::cloneMode(const std::string& originId, const CSMWorld::UniversalId::Type type)
|
||||||
|
{
|
||||||
|
GenericCreator::cloneMode(originId, type);
|
||||||
|
|
||||||
|
int x = 0, y = 0;
|
||||||
|
CSMWorld::Land::parseUniqueRecordId(originId, x, y);
|
||||||
|
|
||||||
|
mX->setValue(x);
|
||||||
|
mY->setValue(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandCreator::touch(const std::vector<CSMWorld::UniversalId>& ids)
|
||||||
|
{
|
||||||
|
// Combine multiple touch commands into one "macro" command
|
||||||
|
getUndoStack().beginMacro("Touch records");
|
||||||
|
|
||||||
|
CSMWorld::IdTable& lands = dynamic_cast<CSMWorld::IdTable&>(*getData().getTableModel(CSMWorld::UniversalId::Type_Lands));
|
||||||
|
CSMWorld::IdTable& ltexs = dynamic_cast<CSMWorld::IdTable&>(*getData().getTableModel(CSMWorld::UniversalId::Type_LandTextures));
|
||||||
|
for (const CSMWorld::UniversalId& uid : ids)
|
||||||
|
{
|
||||||
|
CSMWorld::TouchLandCommand* touchCmd = new CSMWorld::TouchLandCommand(lands, ltexs, uid.getId());
|
||||||
|
getUndoStack().push(touchCmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
getUndoStack().endMacro();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandCreator::focus()
|
||||||
|
{
|
||||||
|
mX->setFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandCreator::reset()
|
||||||
|
{
|
||||||
|
GenericCreator::reset();
|
||||||
|
mX->setValue(0);
|
||||||
|
mY->setValue(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string LandCreator::getErrors() const
|
||||||
|
{
|
||||||
|
if (getData().getLand().searchId(getId()) >= 0)
|
||||||
|
return "A land with that name already exists.";
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string LandCreator::getId() const
|
||||||
|
{
|
||||||
|
return CSMWorld::Land::createUniqueRecordId(mX->value(), mY->value());
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandCreator::pushCommand(std::unique_ptr<CSMWorld::CreateCommand> command, const std::string& id)
|
||||||
|
{
|
||||||
|
if (mCloneMode)
|
||||||
|
{
|
||||||
|
CSMWorld::IdTable& lands = dynamic_cast<CSMWorld::IdTable&>(*getData().getTableModel(CSMWorld::UniversalId::Type_Lands));
|
||||||
|
CSMWorld::IdTable& ltexs = dynamic_cast<CSMWorld::IdTable&>(*getData().getTableModel(CSMWorld::UniversalId::Type_LandTextures));
|
||||||
|
|
||||||
|
getUndoStack().beginMacro(("Clone " + id).c_str());
|
||||||
|
getUndoStack().push(command.release());
|
||||||
|
|
||||||
|
CSMWorld::CopyLandTexturesCommand* ltexCopy = new CSMWorld::CopyLandTexturesCommand(lands, ltexs, getClonedId(), getId());
|
||||||
|
getUndoStack().push(ltexCopy);
|
||||||
|
|
||||||
|
getUndoStack().endMacro();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
getUndoStack().push (command.release());
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandCreator::coordChanged(int value)
|
||||||
|
{
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
#ifndef CSV_WORLD_LANDCREATOR_H
|
||||||
|
#define CSV_WORLD_LANDCREATOR_H
|
||||||
|
|
||||||
|
#include "genericcreator.hpp"
|
||||||
|
|
||||||
|
class QLabel;
|
||||||
|
class QSpinBox;
|
||||||
|
|
||||||
|
namespace CSVWorld
|
||||||
|
{
|
||||||
|
class LandCreator : public GenericCreator
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
QLabel* mXLabel;
|
||||||
|
QLabel* mYLabel;
|
||||||
|
QSpinBox* mX;
|
||||||
|
QSpinBox* mY;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
LandCreator(CSMWorld::Data& data, QUndoStack& undoStack, const CSMWorld::UniversalId& id);
|
||||||
|
|
||||||
|
void cloneMode(const std::string& originId, const CSMWorld::UniversalId::Type type) override;
|
||||||
|
|
||||||
|
void touch(const std::vector<CSMWorld::UniversalId>& ids) override;
|
||||||
|
|
||||||
|
void focus() override;
|
||||||
|
|
||||||
|
void reset() override;
|
||||||
|
|
||||||
|
std::string getErrors() const override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
std::string getId() const override;
|
||||||
|
|
||||||
|
void pushCommand(std::unique_ptr<CSMWorld::CreateCommand> command,
|
||||||
|
const std::string& id) override;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void coordChanged(int value);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,101 @@
|
|||||||
|
#include "landtexturecreator.hpp"
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QSpinBox>
|
||||||
|
|
||||||
|
#include "../../model/world/commands.hpp"
|
||||||
|
#include "../../model/world/idtable.hpp"
|
||||||
|
#include "../../model/world/landtexture.hpp"
|
||||||
|
|
||||||
|
namespace CSVWorld
|
||||||
|
{
|
||||||
|
LandTextureCreator::LandTextureCreator(CSMWorld::Data& data, QUndoStack& undoStack, const CSMWorld::UniversalId& id)
|
||||||
|
: GenericCreator(data, undoStack, id)
|
||||||
|
{
|
||||||
|
// One index is reserved for a default texture
|
||||||
|
const size_t MaxIndex = std::numeric_limits<uint16_t>::max() - 1;
|
||||||
|
|
||||||
|
setManualEditing(false);
|
||||||
|
|
||||||
|
QLabel* nameLabel = new QLabel("Name");
|
||||||
|
insertBeforeButtons(nameLabel, false);
|
||||||
|
|
||||||
|
mNameEdit = new QLineEdit(this);
|
||||||
|
insertBeforeButtons(mNameEdit, true);
|
||||||
|
|
||||||
|
QLabel* indexLabel = new QLabel("Index");
|
||||||
|
insertBeforeButtons(indexLabel, false);
|
||||||
|
|
||||||
|
mIndexBox = new QSpinBox(this);
|
||||||
|
mIndexBox->setMinimum(0);
|
||||||
|
mIndexBox->setMaximum(MaxIndex);
|
||||||
|
insertBeforeButtons(mIndexBox, true);
|
||||||
|
|
||||||
|
connect(mNameEdit, SIGNAL(textChanged(const QString&)), this, SLOT(nameChanged(const QString&)));
|
||||||
|
connect(mIndexBox, SIGNAL(valueChanged(int)), this, SLOT(indexChanged(int)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandTextureCreator::cloneMode(const std::string& originId, const CSMWorld::UniversalId::Type type)
|
||||||
|
{
|
||||||
|
GenericCreator::cloneMode(originId, type);
|
||||||
|
|
||||||
|
CSMWorld::IdTable& table = dynamic_cast<CSMWorld::IdTable&>(*getData().getTableModel(getCollectionId()));
|
||||||
|
|
||||||
|
int column = table.findColumnIndex(CSMWorld::Columns::ColumnId_TextureNickname);
|
||||||
|
mNameEdit->setText((table.data(table.getModelIndex(originId, column)).toString()));
|
||||||
|
|
||||||
|
column = table.findColumnIndex(CSMWorld::Columns::ColumnId_TextureIndex);
|
||||||
|
mIndexBox->setValue((table.data(table.getModelIndex(originId, column)).toInt()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandTextureCreator::focus()
|
||||||
|
{
|
||||||
|
mIndexBox->setFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandTextureCreator::reset()
|
||||||
|
{
|
||||||
|
GenericCreator::reset();
|
||||||
|
mNameEdit->setText("");
|
||||||
|
mIndexBox->setValue(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string LandTextureCreator::getErrors() const
|
||||||
|
{
|
||||||
|
if (getData().getLandTextures().searchId(getId()) >= 0)
|
||||||
|
{
|
||||||
|
return "Index is already in use";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandTextureCreator::configureCreateCommand(CSMWorld::CreateCommand& command) const
|
||||||
|
{
|
||||||
|
GenericCreator::configureCreateCommand(command);
|
||||||
|
|
||||||
|
CSMWorld::IdTable& table = dynamic_cast<CSMWorld::IdTable&>(*getData().getTableModel(getCollectionId()));
|
||||||
|
int column = table.findColumnIndex(CSMWorld::Columns::ColumnId_TextureNickname);
|
||||||
|
command.addValue(column, mName.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string LandTextureCreator::getId() const
|
||||||
|
{
|
||||||
|
return CSMWorld::LandTexture::createUniqueRecordId(0, mIndexBox->value());
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandTextureCreator::nameChanged(const QString& value)
|
||||||
|
{
|
||||||
|
mName = value.toUtf8().constData();
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandTextureCreator::indexChanged(int value)
|
||||||
|
{
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
#ifndef CSV_WORLD_LANDTEXTURECREATOR_H
|
||||||
|
#define CSV_WORLD_LANDTEXTURECREATOR_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "genericcreator.hpp"
|
||||||
|
|
||||||
|
class QLineEdit;
|
||||||
|
class QSpinBox;
|
||||||
|
|
||||||
|
namespace CSVWorld
|
||||||
|
{
|
||||||
|
class LandTextureCreator : public GenericCreator
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
LandTextureCreator(CSMWorld::Data& data, QUndoStack& undoStack, const CSMWorld::UniversalId& id);
|
||||||
|
|
||||||
|
void cloneMode(const std::string& originId, const CSMWorld::UniversalId::Type type) override;
|
||||||
|
|
||||||
|
void focus() override;
|
||||||
|
|
||||||
|
void reset() override;
|
||||||
|
|
||||||
|
std::string getErrors() const override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
void configureCreateCommand(CSMWorld::CreateCommand& command) const override;
|
||||||
|
|
||||||
|
std::string getId() const override;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void nameChanged(const QString& val);
|
||||||
|
void indexChanged(int val);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
QLineEdit* mNameEdit;
|
||||||
|
QSpinBox* mIndexBox;
|
||||||
|
|
||||||
|
std::string mName;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,283 @@
|
|||||||
|
#include "keyboardnavigation.hpp"
|
||||||
|
|
||||||
|
#include <MyGUI_InputManager.h>
|
||||||
|
#include <MyGUI_WidgetManager.h>
|
||||||
|
#include <MyGUI_Button.h>
|
||||||
|
#include <MyGUI_Gui.h>
|
||||||
|
#include <MyGUI_Window.h>
|
||||||
|
|
||||||
|
#include "../mwbase/windowmanager.hpp"
|
||||||
|
#include "../mwbase/environment.hpp"
|
||||||
|
|
||||||
|
namespace MWGui
|
||||||
|
{
|
||||||
|
|
||||||
|
bool shouldAcceptKeyFocus(MyGUI::Widget* w)
|
||||||
|
{
|
||||||
|
return w && !w->castType<MyGUI::Window>(false) && w->getInheritedEnabled() && w->getInheritedVisible() && w->getVisible() && w->getEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Recursively get all child widgets that accept keyboard input
|
||||||
|
void getKeyFocusWidgets(MyGUI::Widget* parent, std::vector<MyGUI::Widget*>& results)
|
||||||
|
{
|
||||||
|
if (!parent->getVisible() || !parent->getEnabled())
|
||||||
|
return;
|
||||||
|
|
||||||
|
MyGUI::EnumeratorWidgetPtr enumerator = parent->getEnumerator();
|
||||||
|
while (enumerator.next())
|
||||||
|
{
|
||||||
|
MyGUI::Widget* w = enumerator.current();
|
||||||
|
if (!w->getVisible() || !w->getEnabled())
|
||||||
|
continue;
|
||||||
|
if (w->getNeedKeyFocus() && shouldAcceptKeyFocus(w))
|
||||||
|
results.push_back(w);
|
||||||
|
else
|
||||||
|
getKeyFocusWidgets(w, results);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyboardNavigation::KeyboardNavigation()
|
||||||
|
: mCurrentFocus(nullptr)
|
||||||
|
, mModalWindow(nullptr)
|
||||||
|
{
|
||||||
|
MyGUI::WidgetManager::getInstance().registerUnlinker(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyboardNavigation::~KeyboardNavigation()
|
||||||
|
{
|
||||||
|
MyGUI::WidgetManager::getInstance().unregisterUnlinker(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeyboardNavigation::saveFocus(int mode)
|
||||||
|
{
|
||||||
|
MyGUI::Widget* focus = MyGUI::InputManager::getInstance().getKeyFocusWidget();
|
||||||
|
if (shouldAcceptKeyFocus(focus))
|
||||||
|
{
|
||||||
|
mKeyFocus[mode] = focus;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mKeyFocus[mode] = mCurrentFocus;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeyboardNavigation::restoreFocus(int mode)
|
||||||
|
{
|
||||||
|
std::map<int, MyGUI::Widget*>::const_iterator found = mKeyFocus.find(mode);
|
||||||
|
if (found != mKeyFocus.end())
|
||||||
|
{
|
||||||
|
MyGUI::Widget* w = found->second;
|
||||||
|
if (w && w->getVisible() && w->getEnabled())
|
||||||
|
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(found->second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeyboardNavigation::_unlinkWidget(MyGUI::Widget *widget)
|
||||||
|
{
|
||||||
|
for (std::pair<const int, MyGUI::Widget*>& w : mKeyFocus)
|
||||||
|
if (w.second == widget)
|
||||||
|
w.second = nullptr;
|
||||||
|
if (widget == mCurrentFocus)
|
||||||
|
mCurrentFocus = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void styleFocusedButton(MyGUI::Widget* w)
|
||||||
|
{
|
||||||
|
if (w)
|
||||||
|
{
|
||||||
|
if (MyGUI::Button* b = w->castType<MyGUI::Button>(false))
|
||||||
|
{
|
||||||
|
b->_setWidgetState("highlighted");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isRootParent(MyGUI::Widget* widget, MyGUI::Widget* root)
|
||||||
|
{
|
||||||
|
while (widget && widget->getParent())
|
||||||
|
widget = widget->getParent();
|
||||||
|
return widget == root;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeyboardNavigation::onFrame()
|
||||||
|
{
|
||||||
|
MyGUI::Widget* focus = MyGUI::InputManager::getInstance().getKeyFocusWidget();
|
||||||
|
|
||||||
|
if (focus == mCurrentFocus)
|
||||||
|
{
|
||||||
|
styleFocusedButton(mCurrentFocus);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// workaround incorrect key focus resets (fix in MyGUI TBD)
|
||||||
|
if (!shouldAcceptKeyFocus(focus) && shouldAcceptKeyFocus(mCurrentFocus) && (!mModalWindow || isRootParent(mCurrentFocus, mModalWindow)))
|
||||||
|
{
|
||||||
|
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mCurrentFocus);
|
||||||
|
focus = mCurrentFocus;
|
||||||
|
}
|
||||||
|
|
||||||
|
// style highlighted button (won't be needed for MyGUI 3.2.3)
|
||||||
|
if (focus != mCurrentFocus)
|
||||||
|
{
|
||||||
|
if (mCurrentFocus)
|
||||||
|
{
|
||||||
|
if (MyGUI::Button* b = mCurrentFocus->castType<MyGUI::Button>(false))
|
||||||
|
b->_setWidgetState("normal");
|
||||||
|
}
|
||||||
|
|
||||||
|
mCurrentFocus = focus;
|
||||||
|
}
|
||||||
|
|
||||||
|
styleFocusedButton(mCurrentFocus);
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeyboardNavigation::setDefaultFocus(MyGUI::Widget *window, MyGUI::Widget *defaultFocus)
|
||||||
|
{
|
||||||
|
MyGUI::Widget* focus = MyGUI::InputManager::getInstance().getKeyFocusWidget();
|
||||||
|
if (!focus || !shouldAcceptKeyFocus(focus))
|
||||||
|
{
|
||||||
|
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(defaultFocus);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!isRootParent(focus, window))
|
||||||
|
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(defaultFocus);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeyboardNavigation::setModalWindow(MyGUI::Widget *window)
|
||||||
|
{
|
||||||
|
mModalWindow = window;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Direction
|
||||||
|
{
|
||||||
|
D_Left,
|
||||||
|
D_Up,
|
||||||
|
D_Right,
|
||||||
|
D_Down,
|
||||||
|
D_Next,
|
||||||
|
D_Prev
|
||||||
|
};
|
||||||
|
|
||||||
|
bool KeyboardNavigation::injectKeyPress(MyGUI::KeyCode key, unsigned int text)
|
||||||
|
{
|
||||||
|
switch (key.getValue())
|
||||||
|
{
|
||||||
|
case MyGUI::KeyCode::ArrowLeft:
|
||||||
|
return switchFocus(D_Left, false);
|
||||||
|
case MyGUI::KeyCode::ArrowRight:
|
||||||
|
return switchFocus(D_Right, false);
|
||||||
|
case MyGUI::KeyCode::ArrowUp:
|
||||||
|
return switchFocus(D_Up, false);
|
||||||
|
case MyGUI::KeyCode::ArrowDown:
|
||||||
|
return switchFocus(D_Down, false);
|
||||||
|
case MyGUI::KeyCode::Tab:
|
||||||
|
return switchFocus(MyGUI::InputManager::getInstance().isShiftPressed() ? D_Prev : D_Next, true);
|
||||||
|
case MyGUI::KeyCode::Return:
|
||||||
|
case MyGUI::KeyCode::NumpadEnter:
|
||||||
|
case MyGUI::KeyCode::Space:
|
||||||
|
return accept();
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool KeyboardNavigation::switchFocus(int direction, bool wrap)
|
||||||
|
{
|
||||||
|
MyGUI::Widget* focus = MyGUI::InputManager::getInstance().getKeyFocusWidget();
|
||||||
|
|
||||||
|
bool isCycle = (direction == D_Prev || direction == D_Next);
|
||||||
|
|
||||||
|
if ((focus && focus->getTypeName().find("Button") == std::string::npos) && !isCycle)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (focus && isCycle && focus->getUserString("AcceptTab") == "true")
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if ((!focus || !focus->getNeedKeyFocus()) && isCycle)
|
||||||
|
{
|
||||||
|
// if nothing is selected, select the first widget
|
||||||
|
return selectFirstWidget();
|
||||||
|
}
|
||||||
|
if (!focus)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
MyGUI::Widget* window = focus;
|
||||||
|
while (window && window->getParent())
|
||||||
|
window = window->getParent();
|
||||||
|
MyGUI::VectorWidgetPtr keyFocusList;
|
||||||
|
getKeyFocusWidgets(window, keyFocusList);
|
||||||
|
|
||||||
|
if (keyFocusList.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
MyGUI::VectorWidgetPtr::iterator found = std::find(keyFocusList.begin(), keyFocusList.end(), focus);
|
||||||
|
if (found == keyFocusList.end())
|
||||||
|
{
|
||||||
|
if (isCycle)
|
||||||
|
return selectFirstWidget();
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool forward = (direction == D_Next || direction == D_Right || direction == D_Down);
|
||||||
|
|
||||||
|
int index = found - keyFocusList.begin();
|
||||||
|
index = forward ? (index+1) : (index-1);
|
||||||
|
if (wrap)
|
||||||
|
index = (index + keyFocusList.size())%keyFocusList.size();
|
||||||
|
else
|
||||||
|
index = std::min(std::max(0, index), static_cast<int>(keyFocusList.size())-1);
|
||||||
|
|
||||||
|
MyGUI::Widget* next = keyFocusList[index];
|
||||||
|
int vertdiff = next->getTop() - focus->getTop();
|
||||||
|
int horizdiff = next->getLeft() - focus->getLeft();
|
||||||
|
bool isVertical = std::abs(vertdiff) > std::abs(horizdiff);
|
||||||
|
if (direction == D_Right && (horizdiff <= 0 || isVertical))
|
||||||
|
return false;
|
||||||
|
else if (direction == D_Left && (horizdiff >= 0 || isVertical))
|
||||||
|
return false;
|
||||||
|
else if (direction == D_Down && (vertdiff <= 0 || !isVertical))
|
||||||
|
return false;
|
||||||
|
else if (direction == D_Up && (vertdiff >= 0 || !isVertical))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(keyFocusList[index]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool KeyboardNavigation::selectFirstWidget()
|
||||||
|
{
|
||||||
|
MyGUI::VectorWidgetPtr keyFocusList;
|
||||||
|
MyGUI::EnumeratorWidgetPtr enumerator = MyGUI::Gui::getInstance().getEnumerator();
|
||||||
|
if (mModalWindow)
|
||||||
|
enumerator = mModalWindow->getEnumerator();
|
||||||
|
while (enumerator.next())
|
||||||
|
getKeyFocusWidgets(enumerator.current(), keyFocusList);
|
||||||
|
|
||||||
|
if (!keyFocusList.empty())
|
||||||
|
{
|
||||||
|
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(keyFocusList[0]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool KeyboardNavigation::accept()
|
||||||
|
{
|
||||||
|
MyGUI::Widget* focus = MyGUI::InputManager::getInstance().getKeyFocusWidget();
|
||||||
|
if (!focus)
|
||||||
|
return false;
|
||||||
|
//MyGUI::Button* button = focus->castType<MyGUI::Button>(false);
|
||||||
|
//if (button && button->getEnabled())
|
||||||
|
if (focus->getTypeName().find("Button") != std::string::npos && focus->getEnabled())
|
||||||
|
{
|
||||||
|
focus->eventMouseButtonClick(focus);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
#ifndef OPENMW_MWGUI_KEYBOARDNAVIGATION_H
|
||||||
|
#define OPENMW_MWGUI_KEYBOARDNAVIGATION_H
|
||||||
|
|
||||||
|
#include <MyGUI_KeyCode.h>
|
||||||
|
#include <MyGUI_IUnlinkWidget.h>
|
||||||
|
|
||||||
|
namespace MWGui
|
||||||
|
{
|
||||||
|
|
||||||
|
class KeyboardNavigation : public MyGUI::IUnlinkWidget
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
KeyboardNavigation();
|
||||||
|
~KeyboardNavigation();
|
||||||
|
|
||||||
|
/// @return Was the key handled by this class?
|
||||||
|
bool injectKeyPress(MyGUI::KeyCode key, unsigned int text);
|
||||||
|
|
||||||
|
void saveFocus(int mode);
|
||||||
|
void restoreFocus(int mode);
|
||||||
|
|
||||||
|
void _unlinkWidget(MyGUI::Widget* widget);
|
||||||
|
|
||||||
|
void onFrame();
|
||||||
|
|
||||||
|
/// Set a key focus widget for this window, if one isn't already set.
|
||||||
|
void setDefaultFocus(MyGUI::Widget* window, MyGUI::Widget* defaultFocus);
|
||||||
|
|
||||||
|
void setModalWindow(MyGUI::Widget* window);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool switchFocus(int direction, bool wrap);
|
||||||
|
|
||||||
|
bool selectFirstWidget();
|
||||||
|
|
||||||
|
/// Send button press event to focused button
|
||||||
|
bool accept();
|
||||||
|
|
||||||
|
std::map<int, MyGUI::Widget*> mKeyFocus;
|
||||||
|
|
||||||
|
MyGUI::Widget* mCurrentFocus;
|
||||||
|
MyGUI::Widget* mModalWindow;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue