commit
2ca40f10eb
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
After Width: | Height: | Size: 169 B |
@ -0,0 +1,540 @@
|
||||
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||
// Copyright (C) 2010 Winch Gate Property Limited
|
||||
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// Project includes
|
||||
#include "builder_zone.h"
|
||||
#include "list_zones_widget.h"
|
||||
#include "landscape_actions.h"
|
||||
|
||||
// NeL includes
|
||||
#include <nel/misc/debug.h>
|
||||
|
||||
// Qt includes
|
||||
#include <QtCore/QDir>
|
||||
#include <QtGui/QMessageBox>
|
||||
#include <QtGui/QProgressDialog>
|
||||
|
||||
namespace LandscapeEditor
|
||||
{
|
||||
int LandCounter = 0;
|
||||
|
||||
ZoneBuilder::ZoneBuilder(LandscapeScene *landscapeScene, ListZonesWidget *listZonesWidget, QUndoStack *undoStack)
|
||||
: m_currentZoneRegion(-1),
|
||||
m_pixmapDatabase(0),
|
||||
m_listZonesWidget(listZonesWidget),
|
||||
m_landscapeScene(landscapeScene),
|
||||
m_undoStack(undoStack)
|
||||
{
|
||||
nlassert(m_landscapeScene);
|
||||
m_pixmapDatabase = new PixmapDatabase();
|
||||
m_lastPathName = "";
|
||||
}
|
||||
|
||||
ZoneBuilder::~ZoneBuilder()
|
||||
{
|
||||
delete m_pixmapDatabase;
|
||||
}
|
||||
|
||||
bool ZoneBuilder::init(const QString &pathName, bool displayProgress)
|
||||
{
|
||||
if (pathName.isEmpty())
|
||||
return false;
|
||||
if (pathName != m_lastPathName)
|
||||
{
|
||||
m_lastPathName = pathName;
|
||||
QString zoneBankPath = pathName;
|
||||
zoneBankPath += "/zoneligos/";
|
||||
|
||||
// Init the ZoneBank
|
||||
m_zoneBank.reset();
|
||||
if (!initZoneBank (zoneBankPath))
|
||||
{
|
||||
m_zoneBank.reset();
|
||||
return false;
|
||||
}
|
||||
// Construct the DataBase from the ZoneBank
|
||||
QString zoneBitmapPath = pathName;
|
||||
zoneBitmapPath += "/zonebitmaps/";
|
||||
m_pixmapDatabase->reset();
|
||||
if (!m_pixmapDatabase->loadPixmaps(zoneBitmapPath, m_zoneBank, displayProgress))
|
||||
{
|
||||
m_zoneBank.reset();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void ZoneBuilder::actionLigoTile(const LigoData &data, const ZonePosition &zonePos)
|
||||
{
|
||||
if (m_undoStack == 0)
|
||||
return;
|
||||
|
||||
checkBeginMacro();
|
||||
// nlinfo(QString("%1 %2 %3 (%4 %5)").arg(data.zoneName.c_str()).arg(zonePos.x).arg(zonePos.y).arg(data.posX).arg(data.posY).toUtf8().constData());
|
||||
m_zonePositionList.push_back(zonePos);
|
||||
m_undoStack->push(new LigoTileCommand(data, zonePos, this, m_landscapeScene));
|
||||
}
|
||||
|
||||
void ZoneBuilder::actionLigoMove(uint index, sint32 deltaX, sint32 deltaY)
|
||||
{
|
||||
if (m_undoStack == 0)
|
||||
return;
|
||||
|
||||
checkBeginMacro();
|
||||
//m_undoStack->push(new LigoMoveCommand(index, deltaX, deltaY, this));
|
||||
}
|
||||
|
||||
void ZoneBuilder::actionLigoResize(uint index, sint32 newMinX, sint32 newMaxX, sint32 newMinY, sint32 newMaxY)
|
||||
{
|
||||
if (m_undoStack == 0)
|
||||
return;
|
||||
|
||||
checkBeginMacro();
|
||||
// nlinfo(QString("minX=%1 maxX=%2 minY=%3 maxY=%4").arg(newMinX).arg(newMaxX).arg(newMinY).arg(newMaxY).toUtf8().constData());
|
||||
m_undoStack->push(new LigoResizeCommand(index, newMinX, newMaxX, newMinY, newMaxY, this));
|
||||
}
|
||||
|
||||
void ZoneBuilder::addZone(sint32 posX, sint32 posY)
|
||||
{
|
||||
// Read-only mode
|
||||
if ((m_listZonesWidget == 0) || (m_undoStack == 0))
|
||||
return;
|
||||
|
||||
if (m_landscapeMap.empty())
|
||||
return;
|
||||
|
||||
// Check zone name
|
||||
std::string zoneName = m_listZonesWidget->currentZoneName().toUtf8().constData();
|
||||
if (zoneName.empty())
|
||||
return;
|
||||
|
||||
BuilderZoneRegion *builderZoneRegion = m_landscapeMap.value(m_currentZoneRegion).builderZoneRegion;
|
||||
builderZoneRegion->init(this);
|
||||
|
||||
uint8 rot = uint8(m_listZonesWidget->currentRot());
|
||||
uint8 flip = uint8(m_listZonesWidget->currentFlip());
|
||||
|
||||
NLLIGO::CZoneBankElement *zoneBankElement = getZoneBank().getElementByZoneName(zoneName);
|
||||
|
||||
m_titleAction = QString("Add zone %1,%2").arg(posX).arg(posY);
|
||||
m_createdAction = false;
|
||||
m_zonePositionList.clear();
|
||||
if (m_listZonesWidget->isForce())
|
||||
{
|
||||
builderZoneRegion->addForce(posX, posY, rot, flip, zoneBankElement);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_listZonesWidget->isNotPropogate())
|
||||
builderZoneRegion->addNotPropagate(posX, posY, rot, flip, zoneBankElement);
|
||||
else
|
||||
builderZoneRegion->add(posX, posY, rot, flip, zoneBankElement);
|
||||
}
|
||||
checkEndMacro();
|
||||
}
|
||||
|
||||
void ZoneBuilder::addTransition(const sint32 posX, const sint32 posY)
|
||||
{
|
||||
// Read-only mode
|
||||
if ((m_listZonesWidget == 0) || (m_undoStack == 0))
|
||||
return;
|
||||
|
||||
if (m_landscapeMap.empty())
|
||||
return;
|
||||
|
||||
m_titleAction = QString("Transition zone %1,%2").arg(posX).arg(posY);
|
||||
m_createdAction = false;
|
||||
m_zonePositionList.clear();
|
||||
|
||||
nlinfo(QString("trans %1,%2").arg(posX).arg(posY).toUtf8().constData());
|
||||
|
||||
sint32 x = (sint32)floor(float(posX) / m_landscapeScene->cellSize());
|
||||
sint32 y = (sint32)floor(float(posY) / m_landscapeScene->cellSize());
|
||||
sint32 k;
|
||||
|
||||
// Detect if we are in a transition square to switch
|
||||
BuilderZoneRegion *builderZoneRegion = m_landscapeMap.value(m_currentZoneRegion).builderZoneRegion;
|
||||
builderZoneRegion->init(this);
|
||||
const NLLIGO::CZoneRegion &zoneRegion = currentZoneRegion()->ligoZoneRegion();
|
||||
bool bCutEdgeTouched = false;
|
||||
for (uint8 transPos = 0; transPos < 4; ++transPos)
|
||||
{
|
||||
uint ce = zoneRegion.getCutEdge(x, y, transPos);
|
||||
|
||||
if ((ce > 0) && (ce < 3))
|
||||
for (k = 0; k < 2; ++k)
|
||||
{
|
||||
float xTrans, yTrans;
|
||||
|
||||
if ((transPos == 0) || (transPos == 1))
|
||||
{
|
||||
if (ce == 1)
|
||||
xTrans = m_landscapeScene->cellSize() / 3.0f;
|
||||
else
|
||||
xTrans = 2.0f * m_landscapeScene->cellSize() / 3.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (transPos == 2)
|
||||
xTrans = 0;
|
||||
else
|
||||
xTrans = m_landscapeScene->cellSize();
|
||||
}
|
||||
xTrans += x * m_landscapeScene->cellSize();
|
||||
|
||||
if ((transPos == 2) || (transPos == 3))
|
||||
{
|
||||
if (ce == 1)
|
||||
yTrans = m_landscapeScene->cellSize() / 3.0f;
|
||||
else
|
||||
yTrans = 2.0f * m_landscapeScene->cellSize() / 3.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (transPos == 1)
|
||||
yTrans = 0;
|
||||
else
|
||||
yTrans = m_landscapeScene->cellSize();
|
||||
}
|
||||
yTrans += y * m_landscapeScene->cellSize();
|
||||
|
||||
if ((posX >= (xTrans - m_landscapeScene->cellSize() / 12.0f)) &&
|
||||
(posX <= (xTrans + m_landscapeScene->cellSize() / 12.0f)) &&
|
||||
(posY >= (yTrans - m_landscapeScene->cellSize() / 12.0f)) &&
|
||||
(posY <= (yTrans + m_landscapeScene->cellSize() / 12.0f)))
|
||||
{
|
||||
builderZoneRegion->invertCutEdge (x, y, transPos);
|
||||
bCutEdgeTouched = true;
|
||||
}
|
||||
ce = 3 - ce;
|
||||
}
|
||||
}
|
||||
|
||||
// If not clicked to change the cutEdge so the user want to change the transition
|
||||
if (!bCutEdgeTouched)
|
||||
{
|
||||
builderZoneRegion->cycleTransition (x, y);
|
||||
}
|
||||
checkEndMacro();
|
||||
}
|
||||
|
||||
void ZoneBuilder::delZone(const sint32 posX, const sint32 posY)
|
||||
{
|
||||
if ((m_listZonesWidget == 0) || (m_undoStack == 0))
|
||||
return;
|
||||
|
||||
if (m_landscapeMap.empty())
|
||||
return;
|
||||
|
||||
m_titleAction = QString("Del zone %1,%2").arg(posX).arg(posY);
|
||||
m_createdAction = false;
|
||||
|
||||
BuilderZoneRegion *builderZoneRegion = m_landscapeMap.value(m_currentZoneRegion).builderZoneRegion;
|
||||
|
||||
builderZoneRegion->init(this);
|
||||
builderZoneRegion->del(posX, posY);
|
||||
checkEndMacro();
|
||||
}
|
||||
|
||||
int ZoneBuilder::createZoneRegion()
|
||||
{
|
||||
LandscapeItem landItem;
|
||||
landItem.zoneRegionObject = new ZoneRegionObject();
|
||||
landItem.builderZoneRegion = new BuilderZoneRegion(LandCounter);
|
||||
landItem.builderZoneRegion->init(this);
|
||||
landItem.rectItem = m_landscapeScene->createLayerBlackout(landItem.zoneRegionObject->ligoZoneRegion());
|
||||
|
||||
m_landscapeMap.insert(LandCounter, landItem);
|
||||
if (m_currentZoneRegion == -1)
|
||||
setCurrentZoneRegion(LandCounter);
|
||||
|
||||
calcMask();
|
||||
return LandCounter++;
|
||||
}
|
||||
|
||||
int ZoneBuilder::createZoneRegion(const QString &fileName)
|
||||
{
|
||||
LandscapeItem landItem;
|
||||
landItem.zoneRegionObject = new ZoneRegionObject();
|
||||
landItem.zoneRegionObject->load(fileName.toUtf8().constData());
|
||||
|
||||
if (checkOverlaps(landItem.zoneRegionObject->ligoZoneRegion()))
|
||||
{
|
||||
delete landItem.zoneRegionObject;
|
||||
return -1;
|
||||
}
|
||||
landItem.builderZoneRegion = new BuilderZoneRegion(LandCounter);
|
||||
landItem.builderZoneRegion->init(this);
|
||||
|
||||
m_landscapeScene->addZoneRegion(landItem.zoneRegionObject->ligoZoneRegion());
|
||||
landItem.rectItem = m_landscapeScene->createLayerBlackout(landItem.zoneRegionObject->ligoZoneRegion());
|
||||
m_landscapeMap.insert(LandCounter, landItem);
|
||||
|
||||
if (m_currentZoneRegion == -1)
|
||||
setCurrentZoneRegion(LandCounter);
|
||||
|
||||
calcMask();
|
||||
return LandCounter++;
|
||||
}
|
||||
|
||||
void ZoneBuilder::deleteZoneRegion(int id)
|
||||
{
|
||||
if (m_landscapeMap.contains(id))
|
||||
{
|
||||
if (m_landscapeMap.value(id).rectItem != 0)
|
||||
delete m_landscapeMap.value(id).rectItem;
|
||||
m_landscapeScene->delZoneRegion(m_landscapeMap.value(id).zoneRegionObject->ligoZoneRegion());
|
||||
delete m_landscapeMap.value(id).zoneRegionObject;
|
||||
delete m_landscapeMap.value(id).builderZoneRegion;
|
||||
m_landscapeMap.remove(id);
|
||||
calcMask();
|
||||
}
|
||||
else
|
||||
nlwarning("Landscape (id %i) not found", id);
|
||||
}
|
||||
|
||||
void ZoneBuilder::setCurrentZoneRegion(int id)
|
||||
{
|
||||
if (m_landscapeMap.contains(id))
|
||||
{
|
||||
if (currentIdZoneRegion() != -1)
|
||||
{
|
||||
NLLIGO::CZoneRegion &ligoRegion = m_landscapeMap.value(m_currentZoneRegion).zoneRegionObject->ligoZoneRegion();
|
||||
m_landscapeMap[m_currentZoneRegion].rectItem = m_landscapeScene->createLayerBlackout(ligoRegion);
|
||||
}
|
||||
delete m_landscapeMap.value(id).rectItem;
|
||||
m_landscapeMap[id].rectItem = 0;
|
||||
m_currentZoneRegion = id;
|
||||
calcMask();
|
||||
}
|
||||
else
|
||||
nlwarning("Landscape (id %i) not found", id);
|
||||
}
|
||||
|
||||
int ZoneBuilder::currentIdZoneRegion() const
|
||||
{
|
||||
return m_currentZoneRegion;
|
||||
}
|
||||
|
||||
ZoneRegionObject *ZoneBuilder::currentZoneRegion() const
|
||||
{
|
||||
ZoneRegionObject *result = 0;
|
||||
if (m_landscapeMap.contains(m_currentZoneRegion))
|
||||
result = m_landscapeMap.value(m_currentZoneRegion).zoneRegionObject;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int ZoneBuilder::countZoneRegion() const
|
||||
{
|
||||
return m_landscapeMap.size();
|
||||
}
|
||||
|
||||
ZoneRegionObject *ZoneBuilder::zoneRegion(int id) const
|
||||
{
|
||||
ZoneRegionObject *result = 0;
|
||||
if (m_landscapeMap.contains(id))
|
||||
result = m_landscapeMap.value(id).zoneRegionObject;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool ZoneBuilder::ligoData(LigoData &data, const ZonePosition &zonePos)
|
||||
{
|
||||
if (m_landscapeMap.contains(zonePos.region))
|
||||
{
|
||||
m_landscapeMap.value(zonePos.region).zoneRegionObject->ligoData(data, zonePos.x, zonePos.y);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ZoneBuilder::setLigoData(LigoData &data, const ZonePosition &zonePos)
|
||||
{
|
||||
if (m_landscapeMap.contains(zonePos.region))
|
||||
m_landscapeMap.value(zonePos.region).zoneRegionObject->setLigoData(data, zonePos.x, zonePos.y);
|
||||
}
|
||||
|
||||
bool ZoneBuilder::initZoneBank (const QString &pathName)
|
||||
{
|
||||
QDir *dir = new QDir(pathName);
|
||||
QStringList filters;
|
||||
filters << "*.ligozone";
|
||||
|
||||
// Find all ligozone files in dir
|
||||
QStringList listFiles = dir->entryList(filters, QDir::Files);
|
||||
|
||||
std::string error;
|
||||
Q_FOREACH(QString file, listFiles)
|
||||
{
|
||||
//nlinfo(file.toUtf8().constData());
|
||||
if (!m_zoneBank.addElement((pathName + file).toUtf8().constData(), error))
|
||||
QMessageBox::critical(0, QObject::tr("Landscape editor"), QString(error.c_str()), QMessageBox::Ok);
|
||||
}
|
||||
delete dir;
|
||||
return true;
|
||||
}
|
||||
|
||||
PixmapDatabase *ZoneBuilder::pixmapDatabase() const
|
||||
{
|
||||
return m_pixmapDatabase;
|
||||
}
|
||||
|
||||
QString ZoneBuilder::dataPath() const
|
||||
{
|
||||
return m_lastPathName;
|
||||
}
|
||||
|
||||
bool ZoneBuilder::getZoneMask(sint32 x, sint32 y)
|
||||
{
|
||||
if ((x < m_minX) || (x > m_maxX) ||
|
||||
(y < m_minY) || (y > m_maxY))
|
||||
return true;
|
||||
else
|
||||
return m_zoneMask[(x - m_minX) + (y - m_minY) * (1 + m_maxX - m_minX)];
|
||||
}
|
||||
|
||||
void ZoneBuilder::calcMask()
|
||||
{
|
||||
sint32 x, y;
|
||||
|
||||
m_minY = m_minX = 1000000;
|
||||
m_maxY = m_maxX = -1000000;
|
||||
|
||||
if (m_landscapeMap.size() == 0)
|
||||
return;
|
||||
|
||||
QMapIterator<int, LandscapeItem> i(m_landscapeMap);
|
||||
while (i.hasNext())
|
||||
{
|
||||
i.next();
|
||||
const NLLIGO::CZoneRegion ®ion = i.value().zoneRegionObject->ligoZoneRegion();
|
||||
|
||||
if (m_minX > region.getMinX())
|
||||
m_minX = region.getMinX();
|
||||
if (m_minY > region.getMinY())
|
||||
m_minY = region.getMinY();
|
||||
if (m_maxX < region.getMaxX())
|
||||
m_maxX = region.getMaxX();
|
||||
if (m_maxY < region.getMaxY())
|
||||
m_maxY = region.getMaxY();
|
||||
}
|
||||
|
||||
m_zoneMask.resize ((1 + m_maxX - m_minX) * (1 + m_maxY - m_minY));
|
||||
sint32 stride = (1 + m_maxX - m_minX);
|
||||
for (y = m_minY; y <= m_maxY; ++y)
|
||||
for (x = m_minX; x <= m_maxX; ++x)
|
||||
{
|
||||
m_zoneMask[x - m_minX + (y - m_minY) * stride] = true;
|
||||
|
||||
QMapIterator<int, LandscapeItem> it(m_landscapeMap);
|
||||
while (it.hasNext())
|
||||
{
|
||||
it.next();
|
||||
if (int(it.key()) != m_currentZoneRegion)
|
||||
{
|
||||
const NLLIGO::CZoneRegion ®ion = it.value().zoneRegionObject->ligoZoneRegion();
|
||||
|
||||
const std::string &rSZone = region.getName (x, y);
|
||||
if ((rSZone != STRING_OUT_OF_BOUND) && (rSZone != STRING_UNUSED))
|
||||
{
|
||||
m_zoneMask[x - m_minX + (y - m_minY) * stride] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ZoneBuilder::getZoneAmongRegions(ZonePosition &zonePos, BuilderZoneRegion *builderZoneRegionFrom, sint32 x, sint32 y)
|
||||
{
|
||||
QMapIterator<int, LandscapeItem> it(m_landscapeMap);
|
||||
while (it.hasNext())
|
||||
{
|
||||
it.next();
|
||||
const NLLIGO::CZoneRegion ®ion = it.value().zoneRegionObject->ligoZoneRegion();
|
||||
if ((x < region.getMinX()) || (x > region.getMaxX()) ||
|
||||
(y < region.getMinY()) || (y > region.getMaxY()))
|
||||
continue;
|
||||
if (region.getName(x, y) != STRING_UNUSED)
|
||||
{
|
||||
builderZoneRegionFrom = it.value().builderZoneRegion;
|
||||
zonePos = ZonePosition(x, y, it.key());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// The zone is not present in other region so it is an empty or oob zone of the current region
|
||||
const NLLIGO::CZoneRegion ®ion = zoneRegion(builderZoneRegionFrom->getRegionId())->ligoZoneRegion();
|
||||
if ((x < region.getMinX()) || (x > region.getMaxX()) ||
|
||||
(y < region.getMinY()) || (y > region.getMaxY()))
|
||||
return false; // Out Of Bound
|
||||
|
||||
zonePos = ZonePosition(x, y, builderZoneRegionFrom->getRegionId());
|
||||
return true;
|
||||
}
|
||||
|
||||
void ZoneBuilder::checkBeginMacro()
|
||||
{
|
||||
if (!m_createdAction)
|
||||
{
|
||||
m_createdAction = true;
|
||||
m_undoStack->beginMacro(m_titleAction);
|
||||
m_undoScanRegionCommand = new UndoScanRegionCommand(true, this, m_landscapeScene);
|
||||
m_undoStack->push(m_undoScanRegionCommand);
|
||||
}
|
||||
}
|
||||
|
||||
void ZoneBuilder::checkEndMacro()
|
||||
{
|
||||
if (m_createdAction)
|
||||
{
|
||||
UndoScanRegionCommand *redoScanRegionCommand = new UndoScanRegionCommand(false, this, m_landscapeScene);
|
||||
|
||||
// Sets list positions in which need apply changes
|
||||
m_undoScanRegionCommand->setScanList(m_zonePositionList);
|
||||
redoScanRegionCommand->setScanList(m_zonePositionList);
|
||||
|
||||
// Adds command in the stack
|
||||
m_undoStack->push(redoScanRegionCommand);
|
||||
m_undoStack->endMacro();
|
||||
}
|
||||
}
|
||||
|
||||
bool ZoneBuilder::checkOverlaps(const NLLIGO::CZoneRegion &newZoneRegion)
|
||||
{
|
||||
QMapIterator<int, LandscapeItem> it(m_landscapeMap);
|
||||
while (it.hasNext())
|
||||
{
|
||||
it.next();
|
||||
const NLLIGO::CZoneRegion &zoneRegion = it.value().zoneRegionObject->ligoZoneRegion();
|
||||
for (sint32 y = zoneRegion.getMinY(); y <= zoneRegion.getMaxY(); ++y)
|
||||
for (sint32 x = zoneRegion.getMinX(); x <= zoneRegion.getMaxX(); ++x)
|
||||
{
|
||||
const std::string &refZoneName = zoneRegion.getName(x, y);
|
||||
if (refZoneName != STRING_UNUSED)
|
||||
{
|
||||
const std::string &zoneName = newZoneRegion.getName(x, y);
|
||||
if ((zoneName != STRING_UNUSED) && (zoneName != STRING_OUT_OF_BOUND))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} /* namespace LandscapeEditor */
|
@ -0,0 +1,174 @@
|
||||
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||
// Copyright (C) 2010 Winch Gate Property Limited
|
||||
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef BUILDER_ZONE_H
|
||||
#define BUILDER_ZONE_H
|
||||
|
||||
// Project includes
|
||||
#include "builder_zone_base.h"
|
||||
#include "builder_zone_region.h"
|
||||
#include "zone_region_editor.h"
|
||||
#include "pixmap_database.h"
|
||||
|
||||
// NeL includes
|
||||
#include <nel/ligo/zone_bank.h>
|
||||
#include <nel/ligo/zone_region.h>
|
||||
|
||||
// STL includes
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
// Qt includes
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QString>
|
||||
#include <QtGui/QPixmap>
|
||||
#include <QtGui/QUndoStack>
|
||||
#include <QtGui/QGraphicsRectItem>
|
||||
|
||||
namespace LandscapeEditor
|
||||
{
|
||||
class ListZonesWidget;
|
||||
class LandscapeScene;
|
||||
class UndoScanRegionCommand;
|
||||
|
||||
/**
|
||||
@class ZoneBuilder
|
||||
@brief ZoneBuilder contains all the shared data between the tools and the engine.
|
||||
@details ZoneBank contains the macro zones that is composed of several zones plus a mask.
|
||||
PixmapDatabase contains the graphics for the zones
|
||||
*/
|
||||
class ZoneBuilder
|
||||
{
|
||||
public:
|
||||
ZoneBuilder(LandscapeScene *landscapeScene, ListZonesWidget *listZonesWidget = 0, QUndoStack *undoStack = 0);
|
||||
~ZoneBuilder();
|
||||
|
||||
/// Inits zoneBank and init zone pixmap database
|
||||
bool init(const QString &pathName, bool displayProgress = false);
|
||||
|
||||
void calcMask();
|
||||
|
||||
/// @return false if in point (x, y) placed zone brick, else true
|
||||
bool getZoneMask (sint32 x, sint32 y);
|
||||
|
||||
bool getZoneAmongRegions(ZonePosition &zonePos, BuilderZoneRegion *builderZoneRegionFrom, sint32 x, sint32 y);
|
||||
|
||||
/// Ligo Actions
|
||||
/// @{
|
||||
|
||||
/// Adds the LigoTileCommand in undo stack
|
||||
void actionLigoTile(const LigoData &data, const ZonePosition &zonePos);
|
||||
|
||||
void actionLigoMove(uint index, sint32 deltaX, sint32 deltaY);
|
||||
|
||||
/// Adds the LigoResizeCommand in undo stack
|
||||
void actionLigoResize(uint index, sint32 newMinX, sint32 newMaxX, sint32 newMinY, sint32 newMaxY);
|
||||
/// @}
|
||||
|
||||
/// Zone Bricks
|
||||
/// @{
|
||||
void addZone(const sint32 posX, const sint32 posY);
|
||||
void addTransition(const sint32 posX, const sint32 posY);
|
||||
void delZone(const sint32 posX, const sint32 posY);
|
||||
/// @}
|
||||
|
||||
/// Zone Region
|
||||
/// @{
|
||||
|
||||
/// Creates empty zone region and adds in the workspace
|
||||
/// @return id zone region
|
||||
int createZoneRegion();
|
||||
|
||||
/// Loads zone region from file @fileName and adds in the workspace.
|
||||
/// @return id zone region
|
||||
int createZoneRegion(const QString &fileName);
|
||||
|
||||
/// Unloads zone region from the workspace
|
||||
void deleteZoneRegion(int id);
|
||||
|
||||
/// Sets the current zone region with @id
|
||||
void setCurrentZoneRegion(int id);
|
||||
|
||||
/// @return id the current zone region, if workspace is empty then returns (-1)
|
||||
int currentIdZoneRegion() const;
|
||||
|
||||
ZoneRegionObject *currentZoneRegion() const;
|
||||
int countZoneRegion() const;
|
||||
ZoneRegionObject *zoneRegion(int id) const;
|
||||
bool ligoData(LigoData &data, const ZonePosition &zonePos);
|
||||
void setLigoData(LigoData &data, const ZonePosition &zonePos);
|
||||
/// @}
|
||||
|
||||
// Accessors
|
||||
NLLIGO::CZoneBank &getZoneBank()
|
||||
{
|
||||
return m_zoneBank;
|
||||
}
|
||||
|
||||
PixmapDatabase *pixmapDatabase() const;
|
||||
|
||||
QString dataPath() const;
|
||||
|
||||
private:
|
||||
|
||||
/// Scans ./zoneligos dir and add all *.ligozone files to zoneBank
|
||||
bool initZoneBank (const QString &path);
|
||||
|
||||
/// Checks enabled beginMacro mode for undo stack, if false, then enables mode
|
||||
void checkBeginMacro();
|
||||
|
||||
/// Checks enabled on beginMacro mode for undo stack, if true, then adds UndoScanRegionCommand
|
||||
/// in undo stack and disables beginMacro mode
|
||||
void checkEndMacro();
|
||||
|
||||
/// Checks intersects between them zone regions
|
||||
/// @return true if newZoneRegion intersects with loaded zone regions, else return false
|
||||
bool checkOverlaps(const NLLIGO::CZoneRegion &newZoneRegion);
|
||||
|
||||
struct LandscapeItem
|
||||
{
|
||||
BuilderZoneRegion *builderZoneRegion;
|
||||
ZoneRegionObject *zoneRegionObject;
|
||||
QGraphicsRectItem *rectItem;
|
||||
};
|
||||
|
||||
sint32 m_minX, m_maxX, m_minY, m_maxY;
|
||||
std::vector<bool> m_zoneMask;
|
||||
|
||||
QString m_lastPathName;
|
||||
|
||||
int m_currentZoneRegion;
|
||||
//std::vector<LandscapeItem> m_landscapeItems;
|
||||
QMap<int, LandscapeItem> m_landscapeMap;
|
||||
|
||||
bool m_createdAction;
|
||||
QString m_titleAction;
|
||||
QList<ZonePosition> m_zonePositionList;
|
||||
UndoScanRegionCommand *m_undoScanRegionCommand;
|
||||
|
||||
PixmapDatabase *m_pixmapDatabase;
|
||||
NLLIGO::CZoneBank m_zoneBank;
|
||||
ListZonesWidget *m_listZonesWidget;
|
||||
LandscapeScene *m_landscapeScene;
|
||||
QUndoStack *m_undoStack;
|
||||
};
|
||||
|
||||
} /* namespace LandscapeEditor */
|
||||
|
||||
#endif // BUILDER_ZONE_H
|
@ -0,0 +1,206 @@
|
||||
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||
// Copyright (C) 2010 Winch Gate Property Limited
|
||||
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// Project includes
|
||||
#include "builder_zone_base.h"
|
||||
#include "landscape_scene_base.h"
|
||||
#include "zone_region_editor.h"
|
||||
#include "pixmap_database.h"
|
||||
|
||||
// NeL includes
|
||||
#include <nel/misc/debug.h>
|
||||
|
||||
// Qt includes
|
||||
#include <QtCore/QDir>
|
||||
#include <QtGui/QMessageBox>
|
||||
#include <QtGui/QProgressDialog>
|
||||
|
||||
namespace LandscapeEditor
|
||||
{
|
||||
int NewLandId = 0;
|
||||
|
||||
ZoneBuilderBase::ZoneBuilderBase(LandscapeSceneBase *landscapeScene)
|
||||
: m_pixmapDatabase(0),
|
||||
m_landscapeSceneBase(landscapeScene)
|
||||
{
|
||||
nlassert(m_landscapeSceneBase);
|
||||
m_pixmapDatabase = new PixmapDatabase();
|
||||
m_lastPathName = "";
|
||||
}
|
||||
|
||||
ZoneBuilderBase::~ZoneBuilderBase()
|
||||
{
|
||||
delete m_pixmapDatabase;
|
||||
}
|
||||
|
||||
bool ZoneBuilderBase::init(const QString &pathName, bool displayProgress)
|
||||
{
|
||||
if (pathName.isEmpty())
|
||||
return false;
|
||||
if (pathName != m_lastPathName)
|
||||
{
|
||||
m_lastPathName = pathName;
|
||||
QString zoneBankPath = pathName;
|
||||
zoneBankPath += "/zoneligos/";
|
||||
|
||||
// Init the ZoneBank
|
||||
m_zoneBank.reset();
|
||||
if (!initZoneBank (zoneBankPath))
|
||||
{
|
||||
m_zoneBank.reset();
|
||||
return false;
|
||||
}
|
||||
// Construct the DataBase from the ZoneBank
|
||||
QString zoneBitmapPath = pathName;
|
||||
zoneBitmapPath += "/zonebitmaps/";
|
||||
m_pixmapDatabase->reset();
|
||||
if (!m_pixmapDatabase->loadPixmaps(zoneBitmapPath, m_zoneBank, displayProgress))
|
||||
{
|
||||
m_zoneBank.reset();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int ZoneBuilderBase::loadZoneRegion(const QString &fileName, int defaultId)
|
||||
{
|
||||
LandscapeItem landItem;
|
||||
landItem.zoneRegionObject = new ZoneRegionObject();
|
||||
landItem.zoneRegionObject->load(fileName.toUtf8().constData());
|
||||
|
||||
if (!checkOverlaps(landItem.zoneRegionObject->ligoZoneRegion()))
|
||||
{
|
||||
delete landItem.zoneRegionObject;
|
||||
return -1;
|
||||
}
|
||||
int id = defaultId;
|
||||
if (id == -1)
|
||||
id = NewLandId++;
|
||||
// landItem.builderZoneRegion = new BuilderZoneRegion(LandCounter);
|
||||
// landItem.builderZoneRegion->init(this);
|
||||
|
||||
m_landscapeSceneBase->addZoneRegion(landItem.zoneRegionObject->ligoZoneRegion());
|
||||
// landItem.rectItem = m_landscapeScene->createLayerBlackout(landItem.zoneRegionObject->ligoZoneRegion());
|
||||
m_landscapeMap.insert(id, landItem);
|
||||
|
||||
calcMask();
|
||||
return id;
|
||||
}
|
||||
|
||||
void ZoneBuilderBase::deleteZoneRegion(int id)
|
||||
{
|
||||
if (m_landscapeMap.contains(id))
|
||||
{
|
||||
m_landscapeSceneBase->delZoneRegion(m_landscapeMap.value(id).zoneRegionObject->ligoZoneRegion());
|
||||
delete m_landscapeMap.value(id).zoneRegionObject;
|
||||
// delete m_landscapeMap.value(id).builderZoneRegion;
|
||||
m_landscapeMap.remove(id);
|
||||
calcMask();
|
||||
}
|
||||
else
|
||||
nlwarning("Landscape (id %i) not found", id);
|
||||
}
|
||||
|
||||
int ZoneBuilderBase::countZoneRegion() const
|
||||
{
|
||||
return m_landscapeMap.size();
|
||||
}
|
||||
|
||||
ZoneRegionObject *ZoneBuilderBase::zoneRegion(int id) const
|
||||
{
|
||||
return m_landscapeMap.value(id).zoneRegionObject;
|
||||
}
|
||||
|
||||
bool ZoneBuilderBase::initZoneBank (const QString &pathName)
|
||||
{
|
||||
QDir *dir = new QDir(pathName);
|
||||
QStringList filters;
|
||||
filters << "*.ligozone";
|
||||
|
||||
// Find all ligozone files in dir
|
||||
QStringList listFiles = dir->entryList(filters, QDir::Files);
|
||||
|
||||
std::string error;
|
||||
Q_FOREACH(QString file, listFiles)
|
||||
{
|
||||
//nlinfo(file.toUtf8().constData());
|
||||
if (!m_zoneBank.addElement((pathName + file).toUtf8().constData(), error))
|
||||
QMessageBox::critical(0, QObject::tr("Landscape editor"), QString(error.c_str()), QMessageBox::Ok);
|
||||
}
|
||||
delete dir;
|
||||
return true;
|
||||
}
|
||||
|
||||
PixmapDatabase *ZoneBuilderBase::pixmapDatabase() const
|
||||
{
|
||||
return m_pixmapDatabase;
|
||||
}
|
||||
|
||||
QString ZoneBuilderBase::dataPath() const
|
||||
{
|
||||
return m_lastPathName;
|
||||
}
|
||||
|
||||
void ZoneBuilderBase::calcMask()
|
||||
{
|
||||
m_minY = m_minX = 1000000;
|
||||
m_maxY = m_maxX = -1000000;
|
||||
|
||||
if (m_landscapeMap.size() == 0)
|
||||
return;
|
||||
|
||||
QMapIterator<int, LandscapeItem> i(m_landscapeMap);
|
||||
while (i.hasNext())
|
||||
{
|
||||
i.next();
|
||||
const NLLIGO::CZoneRegion ®ion = i.value().zoneRegionObject->ligoZoneRegion();
|
||||
|
||||
if (m_minX > region.getMinX())
|
||||
m_minX = region.getMinX();
|
||||
if (m_minY > region.getMinY())
|
||||
m_minY = region.getMinY();
|
||||
if (m_maxX < region.getMaxX())
|
||||
m_maxX = region.getMaxX();
|
||||
if (m_maxY < region.getMaxY())
|
||||
m_maxY = region.getMaxY();
|
||||
}
|
||||
}
|
||||
|
||||
bool ZoneBuilderBase::checkOverlaps(const NLLIGO::CZoneRegion &newZoneRegion)
|
||||
{
|
||||
QMapIterator<int, LandscapeItem> it(m_landscapeMap);
|
||||
while (it.hasNext())
|
||||
{
|
||||
it.next();
|
||||
const NLLIGO::CZoneRegion &zoneRegion = it.value().zoneRegionObject->ligoZoneRegion();
|
||||
for (sint32 y = zoneRegion.getMinY(); y <= zoneRegion.getMaxY(); ++y)
|
||||
for (sint32 x = zoneRegion.getMinX(); x <= zoneRegion.getMaxX(); ++x)
|
||||
{
|
||||
const std::string &refZoneName = zoneRegion.getName(x, y);
|
||||
if (refZoneName != STRING_UNUSED)
|
||||
{
|
||||
const std::string &zoneName = newZoneRegion.getName(x, y);
|
||||
if ((zoneName != STRING_UNUSED) && (zoneName != STRING_OUT_OF_BOUND))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} /* namespace LandscapeEditor */
|
@ -0,0 +1,129 @@
|
||||
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||
// Copyright (C) 2010 Winch Gate Property Limited
|
||||
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef BUILDER_ZONE_BASE_H
|
||||
#define BUILDER_ZONE_BASE_H
|
||||
|
||||
// Project includes
|
||||
#include "landscape_editor_global.h"
|
||||
|
||||
// NeL includes
|
||||
#include <nel/ligo/zone_bank.h>
|
||||
#include <nel/ligo/zone_region.h>
|
||||
|
||||
// STL includes
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
// Qt includes
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QString>
|
||||
#include <QtGui/QPixmap>
|
||||
#include <QtGui/QGraphicsRectItem>
|
||||
|
||||
namespace LandscapeEditor
|
||||
{
|
||||
class LandscapeSceneBase;
|
||||
class PixmapDatabase;
|
||||
class ZoneRegionObject;
|
||||
|
||||
// Data
|
||||
struct ZonePosition
|
||||
{
|
||||
// Absolute position
|
||||
sint32 x;
|
||||
sint32 y;
|
||||
int region;
|
||||
|
||||
ZonePosition()
|
||||
{
|
||||
x = 0xffffffff;
|
||||
y = 0xffffffff;
|
||||
region = -1;
|
||||
}
|
||||
|
||||
ZonePosition(const sint32 posX, const sint32 posY, const int id)
|
||||
{
|
||||
x = posX;
|
||||
y = posY;
|
||||
region = id;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@class ZoneBuilderBase
|
||||
@brief ZoneBuilderBase contains all the shared data between the tools and the engine.
|
||||
@details ZoneBank contains the macro zones that is composed of several zones plus a mask.
|
||||
PixmapDatabase contains the graphics for the zones
|
||||
*/
|
||||
class LANDSCAPE_EDITOR_EXPORT ZoneBuilderBase
|
||||
{
|
||||
public:
|
||||
explicit ZoneBuilderBase(LandscapeSceneBase *landscapeScene);
|
||||
virtual ~ZoneBuilderBase();
|
||||
|
||||
/// Init zoneBank and init zone pixmap database
|
||||
bool init(const QString &pathName, bool displayProgress = false);
|
||||
|
||||
/// Zone Region
|
||||
/// @{
|
||||
int loadZoneRegion(const QString &fileName, int defaultId = -1);
|
||||
void deleteZoneRegion(int id);
|
||||
int countZoneRegion() const;
|
||||
ZoneRegionObject *zoneRegion(int id) const;
|
||||
/// @}
|
||||
|
||||
// Accessors
|
||||
NLLIGO::CZoneBank &getZoneBank()
|
||||
{
|
||||
return m_zoneBank;
|
||||
}
|
||||
|
||||
PixmapDatabase *pixmapDatabase() const;
|
||||
|
||||
QString dataPath() const;
|
||||
|
||||
private:
|
||||
|
||||
/// Scan ./zoneligos dir and add all *.ligozone files to zoneBank
|
||||
bool initZoneBank (const QString &path);
|
||||
|
||||
void calcMask();
|
||||
|
||||
bool checkOverlaps(const NLLIGO::CZoneRegion &newZoneRegion);
|
||||
|
||||
struct LandscapeItem
|
||||
{
|
||||
ZoneRegionObject *zoneRegionObject;
|
||||
};
|
||||
|
||||
sint32 m_minX, m_maxX, m_minY, m_maxY;
|
||||
|
||||
QString m_lastPathName;
|
||||
|
||||
QMap<int, LandscapeItem> m_landscapeMap;
|
||||
|
||||
PixmapDatabase *m_pixmapDatabase;
|
||||
NLLIGO::CZoneBank m_zoneBank;
|
||||
LandscapeSceneBase *m_landscapeSceneBase;
|
||||
};
|
||||
|
||||
} /* namespace LandscapeEditor */
|
||||
|
||||
#endif // BUILDER_ZONE_BASE_H
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,107 @@
|
||||
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||
// Copyright (C) 2010 Winch Gate Property Limited
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef BUILDER_ZONE_REGION_H
|
||||
#define BUILDER_ZONE_REGION_H
|
||||
|
||||
// Project includes
|
||||
|
||||
// NeL includes
|
||||
#include <nel/ligo/zone_bank.h>
|
||||
#include <nel/ligo/zone_region.h>
|
||||
|
||||
// STL includes
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <queue>
|
||||
|
||||
// Qt includes
|
||||
|
||||
namespace LandscapeEditor
|
||||
{
|
||||
class ZoneBuilder;
|
||||
class ToUpdate;
|
||||
|
||||
// CZoneRegion contains informations about the zones painted.
|
||||
// (Legacy class from old world editor. It needs to refactoring!)
|
||||
class BuilderZoneRegion
|
||||
{
|
||||
public:
|
||||
|
||||
explicit BuilderZoneRegion(uint regionId);
|
||||
|
||||
// New interface
|
||||
bool init(ZoneBuilder *zoneBuilder);
|
||||
void add(sint32 x, sint32 y, uint8 rot, uint8 flip, NLLIGO::CZoneBankElement *zoneBankElement);
|
||||
void invertCutEdge(sint32 x, sint32 y, uint8 cePos);
|
||||
void cycleTransition(sint32 x, sint32 y);
|
||||
bool addNotPropagate(sint32 x, sint32 y, uint8 rot, uint8 flip, NLLIGO::CZoneBankElement *zoneBankElement);
|
||||
|
||||
/// Brutal adding a zone over empty space do not propagate in any way -> can result
|
||||
/// in inconsistency when trying the propagation mode
|
||||
void addForce (sint32 x, sint32 y, uint8 rot, uint8 flip, NLLIGO::CZoneBankElement *zoneBankElement);
|
||||
void del(sint32 x, sint32 y, bool transition = false, ToUpdate *pUpdate = 0);
|
||||
void move(sint32 x, sint32 y);
|
||||
uint32 countZones();
|
||||
void reduceMin();
|
||||
uint getRegionId() const;
|
||||
|
||||
private:
|
||||
|
||||
// An element of the graph
|
||||
struct SMatNode
|
||||
{
|
||||
std::string Name;
|
||||
// Position in the tree (vector of nodes)
|
||||
std::vector<uint32> Arcs;
|
||||
};
|
||||
|
||||
void addTransition(sint32 x, sint32 y, uint8 rot, uint8 flip, NLLIGO::CZoneBankElement *zoneBankElement);
|
||||
|
||||
void addToUpdateAndCreate(BuilderZoneRegion *builderZoneRegion, sint32 sharePos, sint32 x, sint32 y,
|
||||
const std::string &newMat, ToUpdate *ptCreate, ToUpdate *ptUpdate);
|
||||
|
||||
void putTransitions(sint32 x, sint32 y, const NLLIGO::SPiece &mask, const std::string &matName, ToUpdate *ptUpdate);
|
||||
void updateTrans(sint32 x, sint32 y, NLLIGO::CZoneBankElement *zoneBankElement = 0);
|
||||
|
||||
std::string getNextMatInTree(const std::string &matA, const std::string &matB);
|
||||
|
||||
/// Find the fastest way between posA and posB in the MatTree (Dijkstra)
|
||||
void tryPath(uint32 posA, uint32 posB, std::vector<uint32> &path);
|
||||
|
||||
void set(sint32 x, sint32 y, sint32 posX, sint32 posY, const std::string &zoneName, bool transition = false);
|
||||
void setRot(sint32 x, sint32 y, uint8 rot);
|
||||
void setFlip(sint32 x, sint32 y, uint8 flip);
|
||||
void resize(sint32 newMinX, sint32 newMaxX, sint32 newMinY, sint32 newMaxY);
|
||||
|
||||
void placePiece(sint32 x, sint32 y, uint8 rot, uint8 flip,
|
||||
NLLIGO::SPiece &sMask, NLLIGO::SPiece &sPosX, NLLIGO::SPiece &sPosY,
|
||||
const std::string &eltName);
|
||||
|
||||
uint m_regionId;
|
||||
|
||||
// To use the global mask
|
||||
ZoneBuilder *m_zoneBuilder;
|
||||
|
||||
// The tree of transition between materials
|
||||
std::vector<SMatNode> m_matTree;
|
||||
|
||||
bool m_firstInit;
|
||||
};
|
||||
|
||||
} /* namespace LandscapeEditor */
|
||||
|
||||
#endif // BUILDER_ZONE_REGION_H
|
Binary file not shown.
After Width: | Height: | Size: 4.1 KiB |
Binary file not shown.
After Width: | Height: | Size: 54 KiB |
Binary file not shown.
After Width: | Height: | Size: 30 KiB |
Binary file not shown.
After Width: | Height: | Size: 5.3 KiB |
@ -0,0 +1,178 @@
|
||||
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||
// Copyright (C) 2010 Winch Gate Property Limited
|
||||
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// Project includes
|
||||
#include "landscape_actions.h"
|
||||
#include "builder_zone.h"
|
||||
|
||||
// NeL includes
|
||||
#include <nel/misc/debug.h>
|
||||
|
||||
// Qt includes
|
||||
|
||||
namespace LandscapeEditor
|
||||
{
|
||||
|
||||
LigoTileCommand::LigoTileCommand(const LigoData &data, const ZonePosition &zonePos,
|
||||
ZoneBuilder *zoneBuilder, LandscapeScene *scene,
|
||||
QUndoCommand *parent)
|
||||
: QUndoCommand(parent),
|
||||
m_zoneBuilder(zoneBuilder),
|
||||
m_scene(scene)
|
||||
{
|
||||
// Backup position
|
||||
m_zonePos = zonePos;
|
||||
|
||||
// Backup new data
|
||||
m_newLigoData = data;
|
||||
|
||||
// Backup old data
|
||||
m_zoneBuilder->ligoData(m_oldLigoData, m_zonePos);
|
||||
}
|
||||
|
||||
LigoTileCommand::~LigoTileCommand()
|
||||
{
|
||||
}
|
||||
|
||||
void LigoTileCommand::undo ()
|
||||
{
|
||||
m_zoneBuilder->setLigoData(m_oldLigoData, m_zonePos);
|
||||
}
|
||||
|
||||
void LigoTileCommand::redo ()
|
||||
{
|
||||
m_zoneBuilder->setLigoData(m_newLigoData, m_zonePos);
|
||||
}
|
||||
|
||||
UndoScanRegionCommand::UndoScanRegionCommand(bool direction, ZoneBuilder *zoneBuilder, LandscapeScene *scene, QUndoCommand *parent)
|
||||
: QUndoCommand(parent),
|
||||
m_direction(direction),
|
||||
m_zoneBuilder(zoneBuilder),
|
||||
m_scene(scene)
|
||||
{
|
||||
}
|
||||
|
||||
UndoScanRegionCommand::~UndoScanRegionCommand()
|
||||
{
|
||||
m_zonePositionList.clear();
|
||||
}
|
||||
|
||||
void UndoScanRegionCommand::setScanList(const QList<ZonePosition> &zonePositionList)
|
||||
{
|
||||
m_zonePositionList = zonePositionList;
|
||||
}
|
||||
|
||||
void UndoScanRegionCommand::undo()
|
||||
{
|
||||
if (m_direction)
|
||||
applyChanges();
|
||||
}
|
||||
|
||||
void UndoScanRegionCommand::redo()
|
||||
{
|
||||
if (!m_direction)
|
||||
applyChanges();
|
||||
}
|
||||
|
||||
void UndoScanRegionCommand::applyChanges()
|
||||
{
|
||||
for (int i = 0; i < m_zonePositionList.size(); ++i)
|
||||
m_scene->deleteItemZone(m_zonePositionList.at(i));
|
||||
|
||||
for (int i = 0; i < m_zonePositionList.size(); ++i)
|
||||
{
|
||||
LigoData data;
|
||||
m_zoneBuilder->ligoData(data, m_zonePositionList.at(i));
|
||||
m_scene->createItemZone(data, m_zonePositionList.at(i));
|
||||
}
|
||||
}
|
||||
|
||||
LigoResizeCommand::LigoResizeCommand(int index, sint32 newMinX, sint32 newMaxX,
|
||||
sint32 newMinY, sint32 newMaxY, ZoneBuilder *zoneBuilder,
|
||||
QUndoCommand *parent)
|
||||
: QUndoCommand(parent),
|
||||
m_zoneBuilder(zoneBuilder)
|
||||
{
|
||||
m_index = index;
|
||||
m_newMinX = newMinX;
|
||||
m_newMaxX = newMaxX;
|
||||
m_newMinY = newMinY;
|
||||
m_newMaxY = newMaxY;
|
||||
|
||||
// Backup old region zone
|
||||
m_oldZoneRegion = m_zoneBuilder->zoneRegion(m_index)->ligoZoneRegion();
|
||||
}
|
||||
|
||||
LigoResizeCommand::~LigoResizeCommand()
|
||||
{
|
||||
}
|
||||
|
||||
void LigoResizeCommand::undo ()
|
||||
{
|
||||
// Restore old region zone
|
||||
m_zoneBuilder->zoneRegion(m_index)->setLigoZoneRegion(m_oldZoneRegion);
|
||||
}
|
||||
|
||||
void LigoResizeCommand::redo ()
|
||||
{
|
||||
// Get the zone region
|
||||
NLLIGO::CZoneRegion ®ion = m_zoneBuilder->zoneRegion(m_index)->ligoZoneRegion();
|
||||
|
||||
sint32 i, j;
|
||||
std::vector<LigoData> newZones;
|
||||
newZones.resize((1 + m_newMaxX - m_newMinX) * (1 + m_newMaxY - m_newMinY));
|
||||
|
||||
sint32 newStride = 1 + m_newMaxX - m_newMinX;
|
||||
sint32 Stride = 1 + region.getMaxX() - region.getMinX();
|
||||
|
||||
for (j = m_newMinY; j <= m_newMaxY; ++j)
|
||||
for (i = m_newMinX; i <= m_newMaxX; ++i)
|
||||
{
|
||||
// Ref on the new value
|
||||
LigoData &data = newZones[(i - m_newMinX) + (j - m_newMinY) * newStride];
|
||||
|
||||
// In the old array ?
|
||||
if ((i >= region.getMinX()) && (i <= region.getMaxX()) &&
|
||||
(j >= region.getMinY()) && (j <= region.getMaxY()))
|
||||
{
|
||||
// Backup values
|
||||
m_zoneBuilder->ligoData(data, ZonePosition(i, j, m_index));
|
||||
}
|
||||
}
|
||||
region.resize(m_newMinX, m_newMaxX, m_newMinY, m_newMaxY);
|
||||
|
||||
for (j = m_newMinY; j <= m_newMaxY; ++j)
|
||||
for (i = m_newMinX; i <= m_newMaxX; ++i)
|
||||
{
|
||||
// Ref on the new value
|
||||
const LigoData &data = newZones[(i - m_newMinX) + (j - m_newMinY) * newStride];
|
||||
|
||||
region.setName(i, j, data.zoneName);
|
||||
region.setPosX(i, j, data.posX);
|
||||
region.setPosY(i, j, data.posY);
|
||||
region.setRot(i, j, data.rot);
|
||||
region.setFlip(i, j, data.flip);
|
||||
uint k;
|
||||
for (k = 0; k < 4; k++)
|
||||
{
|
||||
region.setSharingMatNames(i, j, k, data.sharingMatNames[k]);
|
||||
region.setSharingCutEdges(i, j, k, data.sharingCutEdges[k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace LandscapeEditor */
|
@ -0,0 +1,111 @@
|
||||
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||
// Copyright (C) 2010 Winch Gate Property Limited
|
||||
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef LANDSCAPE_ACTIONS_H
|
||||
#define LANDSCAPE_ACTIONS_H
|
||||
|
||||
// Project includes
|
||||
#include "builder_zone.h"
|
||||
#include "landscape_scene.h"
|
||||
|
||||
// NeL includes
|
||||
|
||||
// Qt includes
|
||||
#include <QtGui/QUndoCommand>
|
||||
#include <QtGui/QGraphicsScene>
|
||||
#include <QtGui/QGraphicsItem>
|
||||
|
||||
namespace LandscapeEditor
|
||||
{
|
||||
|
||||
/**
|
||||
@class LigoTileCommand
|
||||
@brief
|
||||
@details
|
||||
*/
|
||||
class LigoTileCommand: public QUndoCommand
|
||||
{
|
||||
public:
|
||||
LigoTileCommand(const LigoData &data, const ZonePosition &zonePos,
|
||||
ZoneBuilder *zoneBuilder, LandscapeScene *scene,
|
||||
QUndoCommand *parent = 0);
|
||||
virtual ~LigoTileCommand();
|
||||
|
||||
virtual void undo();
|
||||
virtual void redo();
|
||||
|
||||
private:
|
||||
ZonePosition m_zonePos;
|
||||
LigoData m_newLigoData;
|
||||
LigoData m_oldLigoData;
|
||||
ZoneBuilder *m_zoneBuilder;
|
||||
LandscapeScene *m_scene;
|
||||
};
|
||||
|
||||
/**
|
||||
@class UndoScanRegionCommand
|
||||
@brief
|
||||
@details
|
||||
*/
|
||||
class UndoScanRegionCommand: public QUndoCommand
|
||||
{
|
||||
public:
|
||||
UndoScanRegionCommand(bool direction, ZoneBuilder *zoneBuilder, LandscapeScene *scene, QUndoCommand *parent = 0);
|
||||
virtual ~UndoScanRegionCommand();
|
||||
|
||||
void setScanList(const QList<ZonePosition> &zonePositionList);
|
||||
virtual void undo();
|
||||
virtual void redo();
|
||||
|
||||
private:
|
||||
void applyChanges();
|
||||
|
||||
bool m_direction;
|
||||
QList<ZonePosition> m_zonePositionList;
|
||||
ZoneBuilder *m_zoneBuilder;
|
||||
LandscapeScene *m_scene;
|
||||
};
|
||||
|
||||
/**
|
||||
@class LigoResizeCommand
|
||||
@brief
|
||||
@details
|
||||
*/
|
||||
class LigoResizeCommand: public QUndoCommand
|
||||
{
|
||||
public:
|
||||
LigoResizeCommand(int index, sint32 newMinX, sint32 newMaxX,
|
||||
sint32 newMinY, sint32 newMaxY, ZoneBuilder *zoneBuilder,
|
||||
QUndoCommand *parent = 0);
|
||||
virtual ~LigoResizeCommand();
|
||||
|
||||
virtual void undo();
|
||||
virtual void redo();
|
||||
|
||||
private:
|
||||
int m_index;
|
||||
sint32 m_newMinX;
|
||||
sint32 m_newMaxX;
|
||||
sint32 m_newMinY;
|
||||
sint32 m_newMaxY;
|
||||
NLLIGO::CZoneRegion m_oldZoneRegion;
|
||||
ZoneBuilder *m_zoneBuilder;
|
||||
};
|
||||
|
||||
} /* namespace LandscapeEditor */
|
||||
|
||||
#endif // LANDSCAPE_ACTIONS_H
|
@ -0,0 +1,498 @@
|
||||
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// Project includes
|
||||
#include "landscape_scene.h"
|
||||
#include "pixmap_database.h"
|
||||
|
||||
// NeL includes
|
||||
#include <nel/misc/debug.h>
|
||||
|
||||
// Qt includes
|
||||
#include <QtGui/QPainter>
|
||||
#include <QtGui/QGraphicsPixmapItem>
|
||||
#include <QtGui/QGraphicsSimpleTextItem>
|
||||
#include <QApplication>
|
||||
|
||||
namespace LandscapeEditor
|
||||
{
|
||||
|
||||
static const int ZONE_NAME = 0;
|
||||
static const int LAYER_ZONES = 2;
|
||||
static const int LAYER_EMPTY_ZONES = 3;
|
||||
static const int LAYER_BLACKOUT = 4;
|
||||
const char *const LAYER_BLACKOUT_NAME = "blackout";
|
||||
|
||||
const int MAX_SCENE_WIDTH = 256;
|
||||
const int MAX_SCENE_HEIGHT = 256;
|
||||
|
||||
LandscapeScene::LandscapeScene(int sizeCell, QObject *parent)
|
||||
: QGraphicsScene(parent),
|
||||
m_cellSize(sizeCell),
|
||||
m_transitionMode(false),
|
||||
m_mouseButton(Qt::NoButton),
|
||||
m_zoneBuilder(0)
|
||||
{
|
||||
setSceneRect(QRectF(0, m_cellSize, MAX_SCENE_WIDTH * m_cellSize, MAX_SCENE_HEIGHT * m_cellSize));
|
||||
}
|
||||
|
||||
LandscapeScene::~LandscapeScene()
|
||||
{
|
||||
}
|
||||
|
||||
int LandscapeScene::cellSize() const
|
||||
{
|
||||
return m_cellSize;
|
||||
}
|
||||
|
||||
void LandscapeScene::setZoneBuilder(ZoneBuilder *zoneBuilder)
|
||||
{
|
||||
m_zoneBuilder = zoneBuilder;
|
||||
}
|
||||
|
||||
QGraphicsItem *LandscapeScene::createItemZone(const LigoData &data, const ZonePosition &zonePos)
|
||||
{
|
||||
if ((data.zoneName == STRING_OUT_OF_BOUND) || (checkUnderZone(zonePos.x, zonePos.y)))
|
||||
return 0;
|
||||
|
||||
if (data.zoneName == STRING_UNUSED)
|
||||
return createItemEmptyZone(zonePos);
|
||||
|
||||
if ((m_zoneBuilder == 0) || (data.zoneName.empty()))
|
||||
return 0;
|
||||
|
||||
// Get image from pixmap database
|
||||
QPixmap *pixmap = m_zoneBuilder->pixmapDatabase()->pixmap(QString(data.zoneName.c_str()));
|
||||
if (pixmap == 0)
|
||||
return 0;
|
||||
|
||||
// Rotate the image counterclockwise
|
||||
QMatrix matrix;
|
||||
matrix.rotate(-data.rot * 90.0);
|
||||
|
||||
QGraphicsPixmapItem *item;
|
||||
|
||||
if (data.flip == 0)
|
||||
{
|
||||
item = addPixmap(pixmap->transformed(matrix, Qt::SmoothTransformation));
|
||||
}
|
||||
else
|
||||
{
|
||||
// mirror image
|
||||
QImage mirrorImage = pixmap->toImage();
|
||||
QPixmap mirrorPixmap = QPixmap::fromImage(mirrorImage.mirrored(true, false));
|
||||
item = addPixmap(mirrorPixmap.transformed(matrix, Qt::SmoothTransformation));
|
||||
}
|
||||
// Enable bilinear filtering
|
||||
item->setTransformationMode(Qt::SmoothTransformation);
|
||||
|
||||
sint32 sizeX = 1, sizeY = 1;
|
||||
sizeX = float(pixmap->width()) / m_zoneBuilder->pixmapDatabase()->textureSize();
|
||||
sizeY = float(pixmap->width()) / m_zoneBuilder->pixmapDatabase()->textureSize();
|
||||
|
||||
sint32 deltaX = 0, deltaY = 0;
|
||||
|
||||
// Calculate offset for graphics item (for items with size that are larger than 1)
|
||||
if ((sizeX > 1) || (sizeY > 1))
|
||||
{
|
||||
if (data.flip == 0)
|
||||
{
|
||||
switch (data.rot)
|
||||
{
|
||||
case 0:
|
||||
deltaX = -data.posX;
|
||||
deltaY = -data.posY + sizeY - 1;
|
||||
break;
|
||||
case 1:
|
||||
deltaX = -(sizeY - 1 - data.posY);
|
||||
deltaY = -data.posX + sizeX - 1;
|
||||
break;
|
||||
case 2:
|
||||
deltaX = -(sizeX - 1 - data.posX);
|
||||
deltaY = data.posY;
|
||||
break;
|
||||
case 3:
|
||||
deltaX = -data.posY;
|
||||
deltaY = data.posX;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (data.rot)
|
||||
{
|
||||
case 0:
|
||||
deltaX = -(sizeX - 1 - data.posX);
|
||||
deltaY = -data.posY + sizeY - 1;
|
||||
break;
|
||||
case 1:
|
||||
deltaX = -(sizeY - 1 - data.posY);
|
||||
deltaY = +data.posX;
|
||||
break;
|
||||
case 2:
|
||||
deltaX = -data.posX;
|
||||
deltaY = data.posY;
|
||||
break;
|
||||
case 3:
|
||||
deltaX = -data.posY;
|
||||
deltaY = -data.posX + sizeX - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set position graphics item with offset for large piece
|
||||
item->setPos((zonePos.x + deltaX) * m_cellSize, (abs(int(zonePos.y + deltaY))) * m_cellSize);
|
||||
|
||||
// The size graphics item should be equal or proportional m_cellSize
|
||||
item->setScale(float(m_cellSize) / m_zoneBuilder->pixmapDatabase()->textureSize());
|
||||
|
||||
item->setData(ZONE_NAME, QString(data.zoneName.c_str()));
|
||||
|
||||
// for not full item zone
|
||||
item->setZValue(LAYER_ZONES);
|
||||
|
||||
item->setShapeMode(QGraphicsPixmapItem::BoundingRectShape);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
QGraphicsItem *LandscapeScene::createItemEmptyZone(const ZonePosition &zonePos)
|
||||
{
|
||||
if (m_zoneBuilder == 0)
|
||||
return 0;
|
||||
|
||||
if (checkUnderZone(zonePos.x, zonePos.y))
|
||||
return 0;
|
||||
|
||||
// Get image from pixmap database
|
||||
QPixmap *pixmap = m_zoneBuilder->pixmapDatabase()->pixmap(QString(STRING_UNUSED));
|
||||
|
||||
if (pixmap == 0)
|
||||
return 0;
|
||||
|
||||
QGraphicsPixmapItem *item = addPixmap(*pixmap);
|
||||
|
||||
// Enable bilinear filtering
|
||||
item->setTransformationMode(Qt::SmoothTransformation);
|
||||
|
||||
// Set position graphics item
|
||||
item->setPos(zonePos.x * m_cellSize, abs(int(zonePos.y)) * m_cellSize);
|
||||
|
||||
// The size graphics item should be equal or proportional m_cellSize
|
||||
item->setScale(float(m_cellSize) / m_zoneBuilder->pixmapDatabase()->textureSize());
|
||||
|
||||
// for not full item zone
|
||||
item->setZValue(LAYER_EMPTY_ZONES);
|
||||
|
||||
item->setShapeMode(QGraphicsPixmapItem::BoundingRectShape);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
QGraphicsRectItem *LandscapeScene::createLayerBlackout(const NLLIGO::CZoneRegion &zoneRegion)
|
||||
{
|
||||
QGraphicsRectItem *rectItem = addRect(zoneRegion.getMinX() * m_cellSize,
|
||||
abs(zoneRegion.getMaxY()) * m_cellSize,
|
||||
(abs(zoneRegion.getMaxX() - zoneRegion.getMinX()) + 1) * m_cellSize,
|
||||
(abs(zoneRegion.getMaxY() - zoneRegion.getMinY()) + 1) * m_cellSize,
|
||||
Qt::NoPen, QBrush(QColor(0, 0, 0, 50)));
|
||||
|
||||
rectItem->setZValue(LAYER_BLACKOUT);
|
||||
rectItem->setData(ZONE_NAME, QString(LAYER_BLACKOUT_NAME));
|
||||
return rectItem;
|
||||
}
|
||||
|
||||
void LandscapeScene::deleteItemZone(const ZonePosition &zonePos)
|
||||
{
|
||||
QGraphicsItem *item = itemAt(zonePos.x * m_cellSize, abs(zonePos.y) * m_cellSize);
|
||||
if ((item != 0) && (item->data(ZONE_NAME).toString() != QString(LAYER_BLACKOUT_NAME)))
|
||||
{
|
||||
removeItem(item);
|
||||
delete item;
|
||||
}
|
||||
}
|
||||
|
||||
void LandscapeScene::addZoneRegion(const NLLIGO::CZoneRegion &zoneRegion)
|
||||
{
|
||||
for (sint32 i = zoneRegion.getMinX(); i <= zoneRegion.getMaxX(); ++i)
|
||||
{
|
||||
for (sint32 j = zoneRegion.getMinY(); j <= zoneRegion.getMaxY(); ++j)
|
||||
{
|
||||
|
||||
std::string zoneName = zoneRegion.getName(i, j);
|
||||
if (zoneName == STRING_UNUSED)
|
||||
{
|
||||
ZonePosition zonePos(i, j, -1);
|
||||
QGraphicsItem *item = createItemEmptyZone(zonePos);
|
||||
}
|
||||
else if (!zoneName.empty())
|
||||
{
|
||||
LigoData data;
|
||||
ZonePosition zonePos(i, j, -1);
|
||||
data.zoneName = zoneName;
|
||||
data.rot = zoneRegion.getRot(i, j);
|
||||
data.flip = zoneRegion.getFlip(i, j);
|
||||
data.posX = zoneRegion.getPosX(i, j);
|
||||
data.posY = zoneRegion.getPosY(i, j);
|
||||
QGraphicsItem *item = createItemZone(data, zonePos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LandscapeScene::delZoneRegion(const NLLIGO::CZoneRegion &zoneRegion)
|
||||
{
|
||||
for (sint32 i = zoneRegion.getMinX(); i <= zoneRegion.getMaxX(); ++i)
|
||||
{
|
||||
for (sint32 j = zoneRegion.getMinY(); j <= zoneRegion.getMaxY(); ++j)
|
||||
{
|
||||
deleteItemZone(ZonePosition(i, -j, -1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LandscapeScene::snapshot(const QString &fileName, int width, int height, const QRectF &landRect)
|
||||
{
|
||||
if (m_zoneBuilder == 0)
|
||||
return;
|
||||
|
||||
// Create image
|
||||
QImage image(landRect.width(), landRect.height(), QImage::Format_RGB888);
|
||||
QPainter painter(&image);
|
||||
painter.setRenderHint(QPainter::Antialiasing, true);
|
||||
|
||||
// Add white background
|
||||
painter.setBrush(QBrush(Qt::white));
|
||||
painter.setPen(Qt::NoPen);
|
||||
painter.drawRect(0, 0, landRect.width(), landRect.height());
|
||||
|
||||
// Paint landscape
|
||||
render(&painter, QRectF(0, 0, landRect.width(), landRect.height()), landRect);
|
||||
|
||||
QImage scaledImage = image.scaled(width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
||||
scaledImage.save(fileName);
|
||||
}
|
||||
|
||||
QString LandscapeScene::zoneNameFromMousePos() const
|
||||
{
|
||||
if ((m_posY > 0) || (m_posY < -MAX_SCENE_HEIGHT) ||
|
||||
(m_posX < 0) || (m_posX > MAX_SCENE_WIDTH))
|
||||
return "NOT A VALID ZONE";
|
||||
|
||||
return QString("%1_%2%3 %4 %5 ").arg(-m_posY).arg(QChar('A' + (m_posX/26))).
|
||||
arg(QChar('A' + (m_posX%26))).arg(m_mouseX, 0,'f',2).arg(-m_mouseY, 0,'f',2);
|
||||
}
|
||||
|
||||
void LandscapeScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
|
||||
{
|
||||
qreal x = mouseEvent->scenePos().x();
|
||||
qreal y = mouseEvent->scenePos().y();
|
||||
if ((x < 0) || (y < 0))
|
||||
return;
|
||||
|
||||
m_posX = sint32(floor(x / m_cellSize));
|
||||
m_posY = sint32(-floor(y / m_cellSize));
|
||||
|
||||
if (m_zoneBuilder == 0)
|
||||
return;
|
||||
if (m_transitionMode)
|
||||
{
|
||||
if (mouseEvent->button() == Qt::LeftButton)
|
||||
|
||||
// Need add offset(= cellSize) on y axes
|
||||
m_zoneBuilder->addTransition(sint(x), sint(-y + m_cellSize));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mouseEvent->button() == Qt::LeftButton)
|
||||
m_zoneBuilder->addZone(m_posX, m_posY);
|
||||
else if (mouseEvent->button() == Qt::RightButton)
|
||||
m_zoneBuilder->delZone(m_posX, m_posY);
|
||||
}
|
||||
m_mouseButton = mouseEvent->button();
|
||||
|
||||
QGraphicsScene::mousePressEvent(mouseEvent);
|
||||
}
|
||||
|
||||
void LandscapeScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
|
||||
{
|
||||
qreal x = mouseEvent->scenePos().x();
|
||||
qreal y = mouseEvent->scenePos().y();
|
||||
|
||||
sint32 posX = sint32(floor(x / m_cellSize));
|
||||
sint32 posY = sint32(-floor(y / m_cellSize));
|
||||
|
||||
if ((m_posX != posX || m_posY != posY) &&
|
||||
(m_mouseButton == Qt::LeftButton ||
|
||||
m_mouseButton == Qt::RightButton))
|
||||
{
|
||||
if (m_transitionMode)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_mouseButton == Qt::LeftButton)
|
||||
m_zoneBuilder->addZone(posX, posY);
|
||||
else if (m_mouseButton == Qt::RightButton)
|
||||
m_zoneBuilder->delZone(posX, posY);
|
||||
}
|
||||
m_posX = posX;
|
||||
m_posY = posY;
|
||||
QApplication::processEvents();
|
||||
}
|
||||
|
||||
m_posX = posX;
|
||||
m_posY = posY;
|
||||
|
||||
m_mouseX = mouseEvent->scenePos().x();
|
||||
m_mouseY = mouseEvent->scenePos().y() - m_cellSize;
|
||||
QGraphicsScene::mouseMoveEvent(mouseEvent);
|
||||
}
|
||||
|
||||
void LandscapeScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent)
|
||||
{
|
||||
m_mouseButton = Qt::NoButton;
|
||||
}
|
||||
|
||||
bool LandscapeScene::checkUnderZone(const int posX, const int posY)
|
||||
{
|
||||
QGraphicsItem *item = itemAt((posX * m_cellSize), abs(posY) * m_cellSize);
|
||||
if (item != 0)
|
||||
{
|
||||
//if (item->data(ZONE_NAME) == QString(LAYER_BLACKOUT_NAME))
|
||||
// return false;
|
||||
//else
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LandscapeScene::transitionMode() const
|
||||
{
|
||||
return m_transitionMode;
|
||||
}
|
||||
|
||||
void LandscapeScene::setTransitionMode(bool enabled)
|
||||
{
|
||||
m_transitionMode = enabled;
|
||||
update();
|
||||
}
|
||||
|
||||
void LandscapeScene::drawForeground(QPainter *painter, const QRectF &rect)
|
||||
{
|
||||
QGraphicsScene::drawForeground(painter, rect);
|
||||
if ((m_zoneBuilder->currentIdZoneRegion() != -1) && (m_transitionMode))
|
||||
drawTransition(painter, rect);
|
||||
}
|
||||
|
||||
void LandscapeScene::drawTransition(QPainter *painter, const QRectF &rect)
|
||||
{
|
||||
int left = int(floor(rect.left() / m_cellSize));
|
||||
int right = int(floor(rect.right() / m_cellSize));
|
||||
int top = int(floor(rect.top() / m_cellSize));
|
||||
int bottom = int(floor(rect.bottom() / m_cellSize));
|
||||
|
||||
QVector<QLine> redLines;
|
||||
QVector<QLine> whiteLines;
|
||||
|
||||
for (int i = left; i < right + 1; ++i)
|
||||
{
|
||||
for (int j = top; j < bottom + 1; ++j)
|
||||
{
|
||||
// Get LIGO data
|
||||
NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->currentZoneRegion()->ligoZoneRegion();
|
||||
uint8 ceUp = zoneRegion.getCutEdge (i, -j, 0);
|
||||
uint8 ceLeft = zoneRegion.getCutEdge (i, -j, 2);
|
||||
if ((ceUp > 0) && (ceUp < 3))
|
||||
{
|
||||
// Calculate position vertical lines
|
||||
int x1, x2, y1, y2;
|
||||
|
||||
y1 = j * m_cellSize + m_cellSize / 12.0f;
|
||||
y2 = y1 - (m_cellSize / 6.0f);
|
||||
|
||||
x1 = i * m_cellSize + 3.0f * m_cellSize / 12.0f;
|
||||
x2 = i * m_cellSize + 5.0f * m_cellSize / 12.0f;
|
||||
if (ceUp == 1)
|
||||
{
|
||||
whiteLines.push_back(QLine(x1, y1, x1, y2));
|
||||
whiteLines.push_back(QLine(x2, y1, x2, y2));
|
||||
}
|
||||
else
|
||||
{
|
||||
redLines.push_back(QLine(x1, y1, x1, y2));
|
||||
redLines.push_back(QLine(x2, y1, x2, y2));
|
||||
}
|
||||
|
||||
x1 = i * m_cellSize + 7.0f * m_cellSize / 12.0f;
|
||||
x2 = i * m_cellSize + 9.0f * m_cellSize / 12.0f;
|
||||
if (ceUp == 1)
|
||||
{
|
||||
redLines.push_back(QLine(x1, y1, x1, y2));
|
||||
redLines.push_back(QLine(x2, y1, x2, y2));
|
||||
}
|
||||
else
|
||||
{
|
||||
whiteLines.push_back(QLine(x1, y1, x1, y2));
|
||||
whiteLines.push_back(QLine(x2, y1, x2, y2));
|
||||
}
|
||||
}
|
||||
if ((ceLeft > 0) && (ceLeft < 3))
|
||||
{
|
||||
// Calculate position horizontal lines
|
||||
int x1, x2, y1, y2;
|
||||
|
||||
x1 = i * m_cellSize - m_cellSize / 12.0f;
|
||||
x2 = x1 + (m_cellSize / 6.0f);
|
||||
|
||||
y1 = j * m_cellSize + 3.0f * m_cellSize / 12.0f;
|
||||
y2 = j * m_cellSize + 5.0f * m_cellSize / 12.0f;
|
||||
if (ceLeft == 1)
|
||||
{
|
||||
redLines.push_back(QLine(x1, y1, x2, y1));
|
||||
redLines.push_back(QLine(x1, y2, x2, y2));
|
||||
}
|
||||
else
|
||||
{
|
||||
whiteLines.push_back(QLine(x1, y1, x2, y1));
|
||||
whiteLines.push_back(QLine(x1, y2, x2, y2));
|
||||
}
|
||||
|
||||
y1 = j * m_cellSize + 7.0f * m_cellSize / 12.0f;
|
||||
y2 = j * m_cellSize + 9.0f * m_cellSize / 12.0f;
|
||||
if (ceLeft == 1)
|
||||
{
|
||||
whiteLines.push_back(QLine(x1, y1, x2, y1));
|
||||
whiteLines.push_back(QLine(x1, y2, x2, y2));
|
||||
}
|
||||
else
|
||||
{
|
||||
redLines.push_back(QLine(x1, y1, x2, y1));
|
||||
redLines.push_back(QLine(x1, y2, x2, y2));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Draw lines
|
||||
painter->setPen(QPen(Qt::red, 0, Qt::SolidLine));
|
||||
painter->drawLines(redLines);
|
||||
painter->setPen(QPen(Qt::white, 0, Qt::SolidLine));
|
||||
painter->drawLines(whiteLines);
|
||||
}
|
||||
|
||||
} /* namespace LandscapeEditor */
|
@ -0,0 +1,89 @@
|
||||
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||
// Copyright (C) 2010 Winch Gate Property Limited
|
||||
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef LANDSCAPE_SCENE_H
|
||||
#define LANDSCAPE_SCENE_H
|
||||
|
||||
// Project includes
|
||||
#include "zone_region_editor.h"
|
||||
#include "builder_zone.h"
|
||||
#include "landscape_editor_global.h"
|
||||
|
||||
// NeL includes
|
||||
#include <nel/ligo/zone_region.h>
|
||||
|
||||
// Qt includes
|
||||
#include <QtGui/QGraphicsScene>
|
||||
#include <QtGui/QGraphicsSceneMouseEvent>
|
||||
|
||||
namespace LandscapeEditor
|
||||
{
|
||||
|
||||
/**
|
||||
@class LandscapeScene
|
||||
@brief
|
||||
@details
|
||||
*/
|
||||
class LandscapeScene : public QGraphicsScene
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
LandscapeScene(int sizeCell = 160, QObject *parent = 0);
|
||||
virtual ~LandscapeScene();
|
||||
|
||||
int cellSize() const;
|
||||
void setZoneBuilder(ZoneBuilder *zoneBuilder);
|
||||
|
||||
QGraphicsItem *createItemZone(const LigoData &data, const ZonePosition &zonePos);
|
||||
QGraphicsItem *createItemEmptyZone(const ZonePosition &zonePos);
|
||||
QGraphicsRectItem *createLayerBlackout(const NLLIGO::CZoneRegion &zoneRegion);
|
||||
void deleteItemZone(const ZonePosition &zonePos);
|
||||
|
||||
void addZoneRegion(const NLLIGO::CZoneRegion &zoneRegion);
|
||||
void delZoneRegion(const NLLIGO::CZoneRegion &zoneRegion);
|
||||
|
||||
void snapshot(const QString &fileName, int width, int height, const QRectF &landRect);
|
||||
|
||||
QString zoneNameFromMousePos() const;
|
||||
bool transitionMode() const;
|
||||
|
||||
public Q_SLOTS:
|
||||
void setTransitionMode(bool enabled);
|
||||
|
||||
protected:
|
||||
virtual void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent);
|
||||
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent);
|
||||
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent);
|
||||
virtual void drawForeground(QPainter *painter, const QRectF &rect);
|
||||
|
||||
void drawTransition(QPainter *painter, const QRectF &rect);
|
||||
|
||||
private:
|
||||
bool checkUnderZone(const int posX, const int posY);
|
||||
|
||||
int m_cellSize;
|
||||
bool m_transitionMode;
|
||||
qreal m_mouseX, m_mouseY;
|
||||
sint32 m_posX, m_posY;
|
||||
Qt::MouseButton m_mouseButton;
|
||||
ZoneBuilder *m_zoneBuilder;
|
||||
};
|
||||
|
||||
} /* namespace LandscapeEditor */
|
||||
|
||||
#endif // LANDSCAPE_SCENE_H
|
@ -0,0 +1,331 @@
|
||||
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// Project includes
|
||||
#include "landscape_scene_base.h"
|
||||
#include "pixmap_database.h"
|
||||
|
||||
// NeL includes
|
||||
#include <nel/misc/debug.h>
|
||||
|
||||
// Qt includes
|
||||
#include <QtGui/QPainter>
|
||||
#include <QtGui/QGraphicsPixmapItem>
|
||||
#include <QtGui/QGraphicsSimpleTextItem>
|
||||
#include <QApplication>
|
||||
|
||||
namespace LandscapeEditor
|
||||
{
|
||||
static const int ZONE_NAME = 0;
|
||||
static const int LAYER_ZONES = 2;
|
||||
static const int LAYER_EMPTY_ZONES = 3;
|
||||
|
||||
// TODO: delete
|
||||
const char *const LAYER_BLACKOUT_NAME = "blackout";
|
||||
|
||||
const int MAX_SCENE_WIDTH = 256;
|
||||
const int MAX_SCENE_HEIGHT = 256;
|
||||
|
||||
LandscapeSceneBase::LandscapeSceneBase(int sizeCell, QObject *parent)
|
||||
: QGraphicsScene(parent),
|
||||
m_cellSize(sizeCell),
|
||||
m_zoneBuilderBase(0)
|
||||
{
|
||||
setSceneRect(QRectF(0, m_cellSize, MAX_SCENE_WIDTH * m_cellSize, MAX_SCENE_HEIGHT * m_cellSize));
|
||||
}
|
||||
|
||||
LandscapeSceneBase::~LandscapeSceneBase()
|
||||
{
|
||||
}
|
||||
|
||||
int LandscapeSceneBase::cellSize() const
|
||||
{
|
||||
return m_cellSize;
|
||||
}
|
||||
|
||||
void LandscapeSceneBase::setZoneBuilder(ZoneBuilderBase *zoneBuilder)
|
||||
{
|
||||
m_zoneBuilderBase = zoneBuilder;
|
||||
}
|
||||
|
||||
QGraphicsItem *LandscapeSceneBase::createItemZone(const LigoData &data, const ZonePosition &zonePos)
|
||||
{
|
||||
if ((data.zoneName == STRING_OUT_OF_BOUND) || (checkUnderZone(zonePos.x, zonePos.y)))
|
||||
return 0;
|
||||
|
||||
if (data.zoneName == STRING_UNUSED)
|
||||
return createItemEmptyZone(zonePos);
|
||||
|
||||
if ((m_zoneBuilderBase == 0) || (data.zoneName.empty()))
|
||||
return 0;
|
||||
|
||||
// Get image from pixmap database
|
||||
QPixmap *pixmap = m_zoneBuilderBase->pixmapDatabase()->pixmap(QString(data.zoneName.c_str()));
|
||||
if (pixmap == 0)
|
||||
return 0;
|
||||
|
||||
// Rotate the image counter clockwise
|
||||
QMatrix matrix;
|
||||
matrix.rotate(-data.rot * 90.0);
|
||||
|
||||
QGraphicsPixmapItem *item;
|
||||
|
||||
if (data.flip == 0)
|
||||
{
|
||||
item = addPixmap(pixmap->transformed(matrix, Qt::SmoothTransformation));
|
||||
}
|
||||
else
|
||||
{
|
||||
// mirror image
|
||||
QImage mirrorImage = pixmap->toImage();
|
||||
QPixmap mirrorPixmap = QPixmap::fromImage(mirrorImage.mirrored(true, false));
|
||||
item = addPixmap(mirrorPixmap.transformed(matrix, Qt::SmoothTransformation));
|
||||
}
|
||||
// Enable bilinear filtering
|
||||
item->setTransformationMode(Qt::SmoothTransformation);
|
||||
|
||||
sint32 sizeX = 1, sizeY = 1;
|
||||
sizeX = float(pixmap->width()) / m_zoneBuilderBase->pixmapDatabase()->textureSize();
|
||||
sizeY = float(pixmap->width()) / m_zoneBuilderBase->pixmapDatabase()->textureSize();
|
||||
|
||||
sint32 deltaX = 0, deltaY = 0;
|
||||
|
||||
// Calculate offset for graphics item (for items with size that are larger than 1)
|
||||
if ((sizeX > 1) || (sizeY > 1))
|
||||
{
|
||||
if (data.flip == 0)
|
||||
{
|
||||
switch (data.rot)
|
||||
{
|
||||
case 0:
|
||||
deltaX = -data.posX;
|
||||
deltaY = -data.posY + sizeY - 1;
|
||||
break;
|
||||
case 1:
|
||||
deltaX = -(sizeY - 1 - data.posY);
|
||||
deltaY = -data.posX + sizeX - 1;
|
||||
break;
|
||||
case 2:
|
||||
deltaX = -(sizeX - 1 - data.posX);
|
||||
deltaY = data.posY;
|
||||
break;
|
||||
case 3:
|
||||
deltaX = -data.posY;
|
||||
deltaY = data.posX;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (data.rot)
|
||||
{
|
||||
case 0:
|
||||
deltaX = -(sizeX - 1 - data.posX);
|
||||
deltaY = -data.posY + sizeY - 1;
|
||||
break;
|
||||
case 1:
|
||||
deltaX = -(sizeY - 1 - data.posY);
|
||||
deltaY = +data.posX;
|
||||
break;
|
||||
case 2:
|
||||
deltaX = -data.posX;
|
||||
deltaY = data.posY;
|
||||
break;
|
||||
case 3:
|
||||
deltaX = -data.posY;
|
||||
deltaY = -data.posX + sizeX - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set position graphics item with offset for large piece
|
||||
item->setPos((zonePos.x + deltaX) * m_cellSize, (abs(int(zonePos.y + deltaY))) * m_cellSize);
|
||||
|
||||
// The size graphics item should be equal or proportional m_cellSize
|
||||
item->setScale(float(m_cellSize) / m_zoneBuilderBase->pixmapDatabase()->textureSize());
|
||||
|
||||
item->setData(ZONE_NAME, QString(data.zoneName.c_str()));
|
||||
|
||||
// for not full item zone
|
||||
item->setZValue(LAYER_ZONES);
|
||||
|
||||
item->setShapeMode(QGraphicsPixmapItem::BoundingRectShape);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
QGraphicsItem *LandscapeSceneBase::createItemEmptyZone(const ZonePosition &zonePos)
|
||||
{
|
||||
if (m_zoneBuilderBase == 0)
|
||||
return 0;
|
||||
|
||||
if (checkUnderZone(zonePos.x, zonePos.y))
|
||||
return 0;
|
||||
|
||||
// Get image from pixmap database
|
||||
QPixmap *pixmap = m_zoneBuilderBase->pixmapDatabase()->pixmap(QString(STRING_UNUSED));
|
||||
if (pixmap == 0)
|
||||
return 0;
|
||||
|
||||
QGraphicsPixmapItem *item = addPixmap(*pixmap);
|
||||
|
||||
// Enable bilinear filtering
|
||||
item->setTransformationMode(Qt::SmoothTransformation);
|
||||
|
||||
// Set position graphics item
|
||||
item->setPos(zonePos.x * m_cellSize, abs(int(zonePos.y)) * m_cellSize);
|
||||
|
||||
// The size graphics item should be equal or proportional m_cellSize
|
||||
item->setScale(float(m_cellSize) / m_zoneBuilderBase->pixmapDatabase()->textureSize());
|
||||
|
||||
// for not full item zone
|
||||
item->setZValue(LAYER_EMPTY_ZONES);
|
||||
|
||||
item->setShapeMode(QGraphicsPixmapItem::BoundingRectShape);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
void LandscapeSceneBase::deleteItemZone(const ZonePosition &zonePos)
|
||||
{
|
||||
QList<QGraphicsItem *> listItems = items(QPointF(zonePos.x * m_cellSize + 10, abs(zonePos.y) * m_cellSize + 10),
|
||||
Qt::IntersectsItemBoundingRect, Qt::AscendingOrder);
|
||||
Q_FOREACH(QGraphicsItem *item, listItems)
|
||||
{
|
||||
if (qgraphicsitem_cast<QGraphicsPixmapItem *>(item) != 0)
|
||||
{
|
||||
removeItem(item);
|
||||
delete item;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LandscapeSceneBase::addZoneRegion(const NLLIGO::CZoneRegion &zoneRegion)
|
||||
{
|
||||
for (sint32 i = zoneRegion.getMinX(); i <= zoneRegion.getMaxX(); ++i)
|
||||
{
|
||||
for (sint32 j = zoneRegion.getMinY(); j <= zoneRegion.getMaxY(); ++j)
|
||||
{
|
||||
|
||||
std::string zoneName = zoneRegion.getName(i, j);
|
||||
if (zoneName == STRING_UNUSED)
|
||||
{
|
||||
ZonePosition zonePos(i, j, -1);
|
||||
QGraphicsItem *item = createItemEmptyZone(zonePos);
|
||||
}
|
||||
else if (!zoneName.empty())
|
||||
{
|
||||
LigoData data;
|
||||
ZonePosition zonePos(i, j, -1);
|
||||
data.zoneName = zoneName;
|
||||
data.rot = zoneRegion.getRot(i, j);
|
||||
data.flip = zoneRegion.getFlip(i, j);
|
||||
data.posX = zoneRegion.getPosX(i, j);
|
||||
data.posY = zoneRegion.getPosY(i, j);
|
||||
QGraphicsItem *item = createItemZone(data, zonePos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LandscapeSceneBase::delZoneRegion(const NLLIGO::CZoneRegion &zoneRegion)
|
||||
{
|
||||
for (sint32 i = zoneRegion.getMinX(); i <= zoneRegion.getMaxX(); ++i)
|
||||
{
|
||||
for (sint32 j = zoneRegion.getMinY(); j <= zoneRegion.getMaxY(); ++j)
|
||||
{
|
||||
|
||||
deleteItemZone(ZonePosition(i, -j, -1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LandscapeSceneBase::snapshot(const QString &fileName, int width, int height, const QRectF &landRect)
|
||||
{
|
||||
if (m_zoneBuilderBase == 0)
|
||||
return;
|
||||
|
||||
// Create image
|
||||
QImage image(landRect.width(), landRect.height(), QImage::Format_RGB888);
|
||||
QPainter painter(&image);
|
||||
painter.setRenderHint(QPainter::Antialiasing, true);
|
||||
|
||||
// Add white background
|
||||
painter.setBrush(QBrush(Qt::white));
|
||||
painter.setPen(Qt::NoPen);
|
||||
painter.drawRect(0, 0, landRect.width(), landRect.height());
|
||||
|
||||
// Paint landscape
|
||||
render(&painter, QRectF(0, 0, landRect.width(), landRect.height()), landRect);
|
||||
|
||||
QImage scaledImage = image.scaled(width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
||||
scaledImage.save(fileName);
|
||||
}
|
||||
|
||||
QString LandscapeSceneBase::zoneNameFromMousePos() const
|
||||
{
|
||||
if ((m_posY > 0) || (m_posY < -MAX_SCENE_HEIGHT) ||
|
||||
(m_posX < 0) || (m_posX > MAX_SCENE_WIDTH))
|
||||
return "NOT A VALID ZONE";
|
||||
|
||||
return QString("%1_%2%3 %4 %5 ").arg(-m_posY+1).arg(QChar('A' + (m_posX/26))).
|
||||
arg(QChar('A' + (m_posX%26))).arg(m_mouseX, 0,'f',2).arg(-m_mouseY, 0,'f',2);
|
||||
}
|
||||
|
||||
void LandscapeSceneBase::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
|
||||
{
|
||||
QGraphicsScene::mousePressEvent(mouseEvent);
|
||||
|
||||
qreal x = mouseEvent->scenePos().x();
|
||||
qreal y = mouseEvent->scenePos().y();
|
||||
m_posX = sint32(floor(x / m_cellSize));
|
||||
m_posY = sint32(-floor(y / m_cellSize));
|
||||
}
|
||||
|
||||
void LandscapeSceneBase::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
|
||||
{
|
||||
m_mouseX = mouseEvent->scenePos().x();
|
||||
m_mouseY = mouseEvent->scenePos().y() - m_cellSize;
|
||||
|
||||
m_posX = sint32(floor(m_mouseX / m_cellSize));
|
||||
m_posY = sint32(-floor(m_mouseY / m_cellSize));
|
||||
|
||||
QGraphicsScene::mouseMoveEvent(mouseEvent);
|
||||
}
|
||||
|
||||
bool LandscapeSceneBase::checkUnderZone(const int posX, const int posY)
|
||||
{
|
||||
// TODO: Why crash program?
|
||||
// QList<QGraphicsItem *> listItems = items(QPointF(posX * m_cellSize + 10, abs(posY) * m_cellSize + 10),
|
||||
// Qt::IntersectsItemBoundingRect, Qt::AscendingOrder);
|
||||
|
||||
QList<QGraphicsItem *> listItems = items();
|
||||
|
||||
QPointF point(posX, abs(posY));
|
||||
Q_FOREACH(QGraphicsItem *item, listItems)
|
||||
{
|
||||
if (item->pos() == point)
|
||||
{
|
||||
if (qgraphicsitem_cast<QGraphicsPixmapItem *>(item) != 0)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} /* namespace LandscapeEditor */
|
@ -0,0 +1,79 @@
|
||||
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef LANDSCAPE_SCENE_BASE_H
|
||||
#define LANDSCAPE_SCENE_BASE_H
|
||||
|
||||
// Project includes
|
||||
#include "landscape_editor_global.h"
|
||||
#include "builder_zone_base.h"
|
||||
#include "zone_region_editor.h"
|
||||
|
||||
// NeL includes
|
||||
#include <nel/ligo/zone_region.h>
|
||||
|
||||
// Qt includes
|
||||
#include <QtGui/QGraphicsScene>
|
||||
#include <QtGui/QGraphicsSceneMouseEvent>
|
||||
|
||||
namespace LandscapeEditor
|
||||
{
|
||||
|
||||
/**
|
||||
@class LandscapeSceneBase
|
||||
@brief
|
||||
@details
|
||||
*/
|
||||
class LANDSCAPE_EDITOR_EXPORT LandscapeSceneBase : public QGraphicsScene
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
LandscapeSceneBase(int sizeCell = 160, QObject *parent = 0);
|
||||
virtual ~LandscapeSceneBase();
|
||||
|
||||
int cellSize() const;
|
||||
void setZoneBuilder(ZoneBuilderBase *zoneBuilder);
|
||||
|
||||
QGraphicsItem *createItemZone(const LigoData &data, const ZonePosition &zonePos);
|
||||
QGraphicsItem *createItemEmptyZone(const ZonePosition &zonePos);
|
||||
void deleteItemZone(const ZonePosition &zonePos);
|
||||
|
||||
void addZoneRegion(const NLLIGO::CZoneRegion &zoneRegion);
|
||||
void delZoneRegion(const NLLIGO::CZoneRegion &zoneRegion);
|
||||
|
||||
void snapshot(const QString &fileName, int width, int height, const QRectF &landRect);
|
||||
|
||||
QString zoneNameFromMousePos() const;
|
||||
|
||||
public Q_SLOTS:
|
||||
|
||||
protected:
|
||||
virtual void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent);
|
||||
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent);
|
||||
|
||||
private:
|
||||
bool checkUnderZone(const int posX, const int posY);
|
||||
|
||||
int m_cellSize;
|
||||
qreal m_mouseX, m_mouseY;
|
||||
sint32 m_posX, m_posY;
|
||||
ZoneBuilderBase *m_zoneBuilderBase;
|
||||
};
|
||||
|
||||
} /* namespace LandscapeEditor */
|
||||
|
||||
#endif // LANDSCAPE_SCENE_BASE_H
|
@ -0,0 +1,254 @@
|
||||
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// Project includes
|
||||
#include "landscape_view.h"
|
||||
#include "landscape_editor_constants.h"
|
||||
|
||||
#include "../core/icore.h"
|
||||
#include "../core/core_constants.h"
|
||||
|
||||
// NeL includes
|
||||
#include <nel/misc/debug.h>
|
||||
|
||||
// Qt includes
|
||||
#include <QApplication>
|
||||
|
||||
namespace LandscapeEditor
|
||||
{
|
||||
|
||||
LandscapeView::LandscapeView(QWidget *parent)
|
||||
: QGraphicsView(parent),
|
||||
m_visibleGrid(true),
|
||||
m_visibleText(true)
|
||||
{
|
||||
setTransformationAnchor(AnchorUnderMouse);
|
||||
setBackgroundBrush(QBrush(Qt::lightGray));
|
||||
|
||||
m_cellSize = 160;
|
||||
m_maxView = 0.06;
|
||||
m_minView = 32.0;
|
||||
m_maxViewText = 0.6;
|
||||
|
||||
//A modified version of centerOn(), handles special cases
|
||||
setCenter(QPointF(500.0, 500.0));
|
||||
}
|
||||
|
||||
LandscapeView::~LandscapeView()
|
||||
{
|
||||
}
|
||||
|
||||
bool LandscapeView::isVisibleGrid() const
|
||||
{
|
||||
return m_visibleGrid;
|
||||
}
|
||||
|
||||
void LandscapeView::setVisibleGrid(bool visible)
|
||||
{
|
||||
m_visibleGrid = visible;
|
||||
scene()->update();
|
||||
}
|
||||
|
||||
void LandscapeView::setVisibleText(bool visible)
|
||||
{
|
||||
m_visibleText = visible;
|
||||
scene()->update();
|
||||
}
|
||||
|
||||
void LandscapeView::wheelEvent(QWheelEvent *event)
|
||||
{
|
||||
//How fast we zoom
|
||||
float numSteps = (( event->delta() / 8 ) / 15) * 1.2;
|
||||
|
||||
QMatrix mat = matrix();
|
||||
QPointF mousePosition = event->pos();
|
||||
|
||||
mat.translate((width() / 2) - mousePosition.x(), (height() / 2) - mousePosition.y());
|
||||
|
||||
if ( numSteps > 0 )
|
||||
mat.scale(numSteps, numSteps);
|
||||
else
|
||||
mat.scale(-1 / numSteps, -1 / numSteps);
|
||||
|
||||
mat.translate(mousePosition.x() - (width() / 2), mousePosition.y() - (height() / 2));
|
||||
|
||||
//Adjust to the new center for correct zooming
|
||||
setMatrix(mat);
|
||||
event->accept();
|
||||
}
|
||||
|
||||
void LandscapeView::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
QGraphicsView::mousePressEvent(event);
|
||||
if (event->button() != Qt::MiddleButton)
|
||||
return;
|
||||
|
||||
//For panning the view
|
||||
m_lastPanPoint = event->pos();
|
||||
setCursor(Qt::ClosedHandCursor);
|
||||
}
|
||||
|
||||
void LandscapeView::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
if(!m_lastPanPoint.isNull())
|
||||
{
|
||||
//Get how much we panned
|
||||
QPointF delta = mapToScene(m_lastPanPoint) - mapToScene(event->pos());
|
||||
m_lastPanPoint = event->pos();
|
||||
|
||||
//Update the center ie. do the pan
|
||||
setCenter(getCenter() + delta);
|
||||
}
|
||||
|
||||
QGraphicsView::mouseMoveEvent(event);
|
||||
}
|
||||
|
||||
void LandscapeView::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
m_lastPanPoint = QPoint();
|
||||
setCursor(Qt::ArrowCursor);
|
||||
QGraphicsView::mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
void LandscapeView::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
//Get the rectangle of the visible area in scene coords
|
||||
QRectF visibleArea = mapToScene(rect()).boundingRect();
|
||||
setCenter(visibleArea.center());
|
||||
|
||||
//Call the subclass resize so the scrollbars are updated correctly
|
||||
QGraphicsView::resizeEvent(event);
|
||||
}
|
||||
|
||||
void LandscapeView::setCenter(const QPointF ¢erPoint)
|
||||
{
|
||||
//Get the rectangle of the visible area in scene coords
|
||||
QRectF visibleArea = mapToScene(rect()).boundingRect();
|
||||
|
||||
//Get the scene area
|
||||
QRectF sceneBounds = sceneRect();
|
||||
|
||||
double boundX = visibleArea.width() / 2.0;
|
||||
double boundY = visibleArea.height() / 2.0;
|
||||
double boundWidth = sceneBounds.width() - 2.0 * boundX;
|
||||
double boundHeight = sceneBounds.height() - 2.0 * boundY;
|
||||
|
||||
//The max boundary that the centerPoint can be to
|
||||
QRectF bounds(boundX, boundY, boundWidth, boundHeight);
|
||||
|
||||
if(bounds.contains(centerPoint))
|
||||
{
|
||||
//We are within the bounds
|
||||
m_currentCenterPoint = centerPoint;
|
||||
}
|
||||
else
|
||||
{
|
||||
//We need to clamp or use the center of the screen
|
||||
if(visibleArea.contains(sceneBounds))
|
||||
{
|
||||
//Use the center of scene ie. we can see the whole scene
|
||||
m_currentCenterPoint = sceneBounds.center();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_currentCenterPoint = centerPoint;
|
||||
|
||||
//We need to clamp the center. The centerPoint is too large
|
||||
if (centerPoint.x() > bounds.x() + bounds.width())
|
||||
m_currentCenterPoint.setX(bounds.x() + bounds.width());
|
||||
else if(centerPoint.x() < bounds.x())
|
||||
m_currentCenterPoint.setX(bounds.x());
|
||||
|
||||
if(centerPoint.y() > bounds.y() + bounds.height())
|
||||
m_currentCenterPoint.setY(bounds.y() + bounds.height());
|
||||
else if(centerPoint.y() < bounds.y())
|
||||
m_currentCenterPoint.setY(bounds.y());
|
||||
}
|
||||
}
|
||||
|
||||
//Update the scrollbars
|
||||
centerOn(m_currentCenterPoint);
|
||||
}
|
||||
|
||||
QPointF LandscapeView::getCenter() const
|
||||
{
|
||||
//return m_currentCenterPoint;
|
||||
return mapToScene(viewport()->rect().center());
|
||||
}
|
||||
|
||||
void LandscapeView::drawForeground(QPainter *painter, const QRectF &rect)
|
||||
{
|
||||
QGraphicsView::drawForeground(painter, rect);
|
||||
|
||||
if (!m_visibleGrid)
|
||||
return;
|
||||
|
||||
painter->setPen(QPen(Qt::white, 0, Qt::SolidLine));
|
||||
drawGrid(painter, rect);
|
||||
|
||||
if (!m_visibleText)
|
||||
return;
|
||||
|
||||
if (transform().m11() > m_maxViewText)
|
||||
{
|
||||
painter->setPen(QPen(Qt::white, 0.5, Qt::SolidLine));
|
||||
drawZoneNames(painter, rect);
|
||||
}
|
||||
}
|
||||
|
||||
void LandscapeView::drawGrid(QPainter *painter, const QRectF &rect)
|
||||
{
|
||||
qreal left = m_cellSize * floor(rect.left() / m_cellSize);
|
||||
qreal top = m_cellSize * floor(rect.top() / m_cellSize);
|
||||
|
||||
QVector<QLine> lines;
|
||||
|
||||
// Calculate vertical lines
|
||||
while (left < rect.right())
|
||||
{
|
||||
lines.push_back(QLine(int(left), int(rect.bottom()), int(left), int(rect.top())));
|
||||
left += m_cellSize;
|
||||
}
|
||||
|
||||
// Calculate horizontal lines
|
||||
while (top < rect.bottom())
|
||||
{
|
||||
lines.push_back(QLine(int(rect.left()), int(top), int(rect.right()), int(top)));
|
||||
top += m_cellSize;
|
||||
}
|
||||
|
||||
// Draw lines
|
||||
painter->drawLines(lines);
|
||||
}
|
||||
|
||||
void LandscapeView::drawZoneNames(QPainter *painter, const QRectF &rect)
|
||||
{
|
||||
int leftSide = int(floor(rect.left() / m_cellSize));
|
||||
int rightSide = int(floor(rect.right() / m_cellSize));
|
||||
int topSide = int(floor(rect.top() / m_cellSize));
|
||||
int bottomSide = int(floor(rect.bottom() / m_cellSize));
|
||||
|
||||
for (int i = leftSide; i < rightSide + 1; ++i)
|
||||
{
|
||||
for (int j = topSide; j < bottomSide + 1; ++j)
|
||||
{
|
||||
QString text = QString("%1_%2%3").arg(j).arg(QChar('A' + (i / 26))).arg(QChar('A' + (i % 26)));
|
||||
painter->drawText(i * m_cellSize + 5, j * m_cellSize + 15, text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace LandscapeEditor */
|
@ -0,0 +1,84 @@
|
||||
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef LANDSCAPE_VIEW_H
|
||||
#define LANDSCAPE_VIEW_H
|
||||
|
||||
// Project includes
|
||||
#include "landscape_editor_global.h"
|
||||
|
||||
// Qt includes
|
||||
#include <QtGui/QGraphicsView>
|
||||
#include <QtGui/QWheelEvent>
|
||||
|
||||
namespace LandscapeEditor
|
||||
{
|
||||
|
||||
/**
|
||||
@class LandscapeView
|
||||
@brief Provides graphics view for viewing zone regions.
|
||||
@details Also provides zooming, panning and displaying grid
|
||||
*/
|
||||
class LANDSCAPE_EDITOR_EXPORT LandscapeView: public QGraphicsView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit LandscapeView(QWidget *parent = 0);
|
||||
virtual ~LandscapeView();
|
||||
|
||||
//Set the current centerpoint in the
|
||||
void setCenter(const QPointF ¢erPoint);
|
||||
QPointF getCenter() const;
|
||||
|
||||
bool isVisibleGrid() const;
|
||||
|
||||
public Q_SLOTS:
|
||||
|
||||
/// Enable/disable displaying grid.
|
||||
void setVisibleGrid(bool visible);
|
||||
|
||||
/// Enable/disable displaying text(coord.) above each zone bricks.
|
||||
void setVisibleText(bool visible);
|
||||
|
||||
private Q_SLOTS:
|
||||
protected:
|
||||
//Take over the interaction
|
||||
virtual void wheelEvent(QWheelEvent *event);
|
||||
virtual void mousePressEvent(QMouseEvent *event);
|
||||
virtual void mouseMoveEvent(QMouseEvent *event);
|
||||
virtual void mouseReleaseEvent(QMouseEvent *event);
|
||||
virtual void drawForeground(QPainter *painter, const QRectF &rect);
|
||||
virtual void resizeEvent(QResizeEvent *event);
|
||||
|
||||
void drawGrid(QPainter *painter, const QRectF &rect);
|
||||
void drawZoneNames(QPainter *painter, const QRectF &rect);
|
||||
private:
|
||||
|
||||
bool m_visibleGrid, m_visibleText;
|
||||
qreal m_maxView, m_minView, m_maxViewText;
|
||||
int m_cellSize;
|
||||
|
||||
//Holds the current centerpoint for the view, used for panning and zooming
|
||||
QPointF m_currentCenterPoint;
|
||||
|
||||
//From panning the view
|
||||
QPoint m_lastPanPoint;
|
||||
}; /* class LandscapeView */
|
||||
|
||||
} /* namespace LandscapeEditor */
|
||||
|
||||
#endif // LANDSCAPE_VIEW_H
|
@ -0,0 +1,137 @@
|
||||
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||
// Copyright (C) 2010 Winch Gate Property Limited
|
||||
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// Project includes
|
||||
#include "list_zones_model.h"
|
||||
#include "builder_zone.h"
|
||||
|
||||
// NeL includes
|
||||
#include <nel/misc/debug.h>
|
||||
|
||||
// STL includes
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
// Qt includes
|
||||
#include <QApplication>
|
||||
#include <QtGui/QProgressDialog>
|
||||
|
||||
namespace LandscapeEditor
|
||||
{
|
||||
|
||||
ListZonesModel::ListZonesModel(int scaleRatio, QObject *parent)
|
||||
: QAbstractListModel(parent),
|
||||
m_scaleRatio(scaleRatio)
|
||||
{
|
||||
|
||||
}
|
||||
ListZonesModel::~ListZonesModel()
|
||||
{
|
||||
resetModel();
|
||||
}
|
||||
|
||||
int ListZonesModel::rowCount(const QModelIndex & /* parent */) const
|
||||
{
|
||||
return m_listNames.count();
|
||||
}
|
||||
|
||||
int ListZonesModel::columnCount(const QModelIndex & /* parent */) const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
QVariant ListZonesModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
switch (role)
|
||||
{
|
||||
case Qt::TextAlignmentRole:
|
||||
return int(Qt::AlignLeft | Qt::AlignVCenter);
|
||||
case Qt::DisplayRole:
|
||||
return m_listNames.at(index.row());
|
||||
case Qt::DecorationRole:
|
||||
{
|
||||
QPixmap *pixmap = getPixmap(m_listNames.at(index.row()));
|
||||
return qVariantFromValue(*pixmap);
|
||||
}
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
QVariant ListZonesModel::headerData(int section, Qt::Orientation, int role) const
|
||||
{
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
void ListZonesModel::setScaleRatio(int scaleRatio)
|
||||
{
|
||||
m_scaleRatio = scaleRatio;
|
||||
}
|
||||
|
||||
void ListZonesModel::setListZones(QStringList &listZones)
|
||||
{
|
||||
beginResetModel();
|
||||
m_listNames.clear();
|
||||
m_listNames = listZones;
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
void ListZonesModel::resetModel()
|
||||
{
|
||||
beginResetModel();
|
||||
QStringList listNames(m_pixmapMap.keys());
|
||||
Q_FOREACH(QString name, listNames)
|
||||
{
|
||||
QPixmap *pixmap = m_pixmapMap.value(name);
|
||||
delete pixmap;
|
||||
}
|
||||
m_pixmapMap.clear();
|
||||
m_listNames.clear();
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
void ListZonesModel::rebuildModel(PixmapDatabase *pixmapDatabase)
|
||||
{
|
||||
resetModel();
|
||||
|
||||
beginResetModel();
|
||||
QStringList listNames;
|
||||
listNames = pixmapDatabase->listPixmaps();
|
||||
|
||||
Q_FOREACH(QString name, listNames)
|
||||
{
|
||||
QPixmap *pixmap = pixmapDatabase->pixmap(name);
|
||||
QPixmap *smallPixmap = new QPixmap(pixmap->scaled(pixmap->width() / m_scaleRatio, pixmap->height() / m_scaleRatio));
|
||||
m_pixmapMap.insert(name, smallPixmap);
|
||||
}
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
QPixmap *ListZonesModel::getPixmap(const QString &zoneName) const
|
||||
{
|
||||
QPixmap *result = 0;
|
||||
if (!m_pixmapMap.contains(zoneName))
|
||||
nlwarning("QPixmap %s not found", zoneName.toUtf8().constData());
|
||||
else
|
||||
result = m_pixmapMap.value(zoneName);
|
||||
return result;
|
||||
}
|
||||
|
||||
} /* namespace LandscapeEditor */
|
@ -0,0 +1,79 @@
|
||||
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||
// Copyright (C) 2010 Winch Gate Property Limited
|
||||
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef LIST_ZONES_MODEL_H
|
||||
#define LIST_ZONES_MODEL_H
|
||||
|
||||
// Project includes
|
||||
|
||||
// NeL includes
|
||||
#include <nel/ligo/zone_bank.h>
|
||||
|
||||
// Qt includes
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QString>
|
||||
#include <QtGui/QPixmap>
|
||||
#include <QAbstractListModel>
|
||||
|
||||
namespace LandscapeEditor
|
||||
{
|
||||
class PixmapDatabase;
|
||||
|
||||
/**
|
||||
@class ListZonesModel
|
||||
@brief ListZonesModel is used for managed list bricks by ListZonesWidget
|
||||
@details ListZonesModel contains the small images for QListView
|
||||
*/
|
||||
class ListZonesModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ListZonesModel(int scaleRatio = 4, QObject *parent = 0);
|
||||
~ListZonesModel();
|
||||
|
||||
int rowCount(const QModelIndex &parent) const;
|
||||
int columnCount(const QModelIndex &parent) const;
|
||||
QVariant data(const QModelIndex &index, int role) const;
|
||||
QVariant headerData(int section, Qt::Orientation orientation,
|
||||
int role) const;
|
||||
|
||||
/// Set size for small pixmaps
|
||||
/// Value should be set before calling rebuildModel
|
||||
void setScaleRatio(int scaleRatio);
|
||||
|
||||
/// Delete all small images and reset model
|
||||
void resetModel();
|
||||
|
||||
/// Set current list zones which will be available in QListView
|
||||
void setListZones(QStringList &listZones);
|
||||
|
||||
/// Build own pixmaps database(all images are scaled: width/scaleRatio, height/scaleRatio) from pixmapDatabase
|
||||
void rebuildModel(PixmapDatabase *pixmapDatabase);
|
||||
|
||||
private:
|
||||
/// Get pixmap
|
||||
/// @return QPixmap* if the image is in the database ; otherwise returns 0.
|
||||
QPixmap *getPixmap(const QString &zoneName) const;
|
||||
|
||||
int m_scaleRatio;
|
||||
QMap<QString, QPixmap *> m_pixmapMap;
|
||||
QStringList m_listNames;
|
||||
};
|
||||
|
||||
} /* namespace LandscapeEditor */
|
||||
|
||||
#endif // LIST_ZONES_MODEL_H
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue