merge from default

This commit is contained in:
dnk-88 2011-08-06 14:05:23 +03:00
commit 34ee367261
70 changed files with 11251 additions and 28 deletions

View file

@ -19,14 +19,15 @@
#include "nel/ligo/zone_bank.h"
#ifdef NL_OS_WINDOWS
#include "nel/misc/debug.h"
#include "nel/misc/file.h"
#include "nel/misc/i_xml.h"
#include "nel/misc/o_xml.h"
#ifdef NL_OS_WINDOWS
#define NOMINMAX
#include <windows.h>
#endif // NL_OS_WINDOWS
using namespace std;
using namespace NLMISC;
@ -496,8 +497,9 @@ void CZoneBank::reset ()
_Selection.clear ();
}
#ifdef NL_OS_WINDOWS
// ---------------------------------------------------------------------------
bool CZoneBank::initFromPath(const string &sPathName, std::string &error)
bool CZoneBank::initFromPath(const std::string &sPathName, std::string &error)
{
char sDirBackup[512];
GetCurrentDirectory (512, sDirBackup);
@ -520,6 +522,7 @@ bool CZoneBank::initFromPath(const string &sPathName, std::string &error)
SetCurrentDirectory (sDirBackup);
return true;
}
#endif // NL_OS_WINDOWS
// ---------------------------------------------------------------------------
bool CZoneBank::addElement (const std::string &elementName, std::string &error)
@ -694,6 +697,4 @@ void CZoneBank::getSelection (std::vector<CZoneBankElement*> &SelectedElements)
// ***************************************************************************
} // namespace NLLIGO
#endif // NL_OS_WINDOWS
} // namespace NLLIGO

View file

@ -1,14 +1,15 @@
ADD_SUBDIRECTORY(core)
ADD_SUBDIRECTORY(example)
ADD_SUBDIRECTORY(ovqt_sheet_builder)
ADD_SUBDIRECTORY(core)
ADD_SUBDIRECTORY(example)
ADD_SUBDIRECTORY(ovqt_sheet_builder)
ADD_SUBDIRECTORY(landscape_editor)
ADD_SUBDIRECTORY(log)
ADD_SUBDIRECTORY(disp_sheet_id)
ADD_SUBDIRECTORY(object_viewer)
ADD_SUBDIRECTORY(zone_painter)
ADD_SUBDIRECTORY(georges_editor)
# Ryzom Specific Plugins
IF(WITH_RYZOM AND WITH_RYZOM_TOOLS)
ADD_SUBDIRECTORY(mission_compiler)
ADD_SUBDIRECTORY(log)
ADD_SUBDIRECTORY(disp_sheet_id)
ADD_SUBDIRECTORY(object_viewer)
ADD_SUBDIRECTORY(zone_painter)
ADD_SUBDIRECTORY(georges_editor)
ADD_SUBDIRECTORY(world_editor)
# Ryzom Specific Plugins
IF(WITH_RYZOM AND WITH_RYZOM_TOOLS)
ADD_SUBDIRECTORY(mission_compiler)
ENDIF(WITH_RYZOM AND WITH_RYZOM_TOOLS)

View file

@ -11,9 +11,19 @@ SET(OVQT_EXT_SYS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/../../extension_system/iplugin.
SET(OVQT_PLUGIN_LANDSCAPE_EDITOR_HDR landscape_editor_plugin.h
landscape_editor_window.h
landscape_scene_base.h
landscape_scene.h
list_zones_model.h
list_zones_widget.h
landscape_view.h
project_settings_dialog.h
snapshot_dialog.h
)
SET(OVQT_PLUGIN_LANDSCAPE_EDITOR_UIS landscape_editor_window.ui
list_zones_widget.ui
project_settings_dialog.ui
shapshot_dialog.ui
)
SET(OVQT_PLUGIN_LANDSCAPE_EDITOR_RCS landscape_editor.qrc)
@ -31,13 +41,13 @@ SOURCE_GROUP(QtGeneratedMocQrcSrc FILES ${OVQT_PLUGIN_LANDSCAPE_EDITOR_MOC_SRC}
SOURCE_GROUP("Landscape Editor Plugin" FILES ${SRC})
SOURCE_GROUP("OVQT Extension System" FILES ${OVQT_EXT_SYS_SRC})
ADD_LIBRARY(ovqt_plugin_landscape_editor MODULE ${SRC}
ADD_LIBRARY(ovqt_plugin_landscape_editor SHARED ${SRC}
${OVQT_PLUGIN_LANDSCAPE_EDITOR_MOC_SRC}
${OVQT_EXT_SYS_SRC}
${OVQT_PLUGIN_LANDSCAPE_EDITOR_UI_HDRS}
${OVQT_PLUGIN_LANDSCAPE_EDITOR_RC_SRCS})
TARGET_LINK_LIBRARIES(ovqt_plugin_landscape_editor ovqt_plugin_core nelmisc nel3d ${QT_LIBRARIES} ${QT_QTOPENGL_LIBRARY})
TARGET_LINK_LIBRARIES(ovqt_plugin_landscape_editor ovqt_plugin_core nelmisc nel3d nelgeorges nelligo ${QT_LIBRARIES} ${QT_QTOPENGL_LIBRARY})
NL_DEFAULT_PROPS(ovqt_plugin_landscape_editor "NeL, Tools, 3D: Object Viewer Qt Plugin: Landscape Editor")
NL_ADD_RUNTIME_FLAGS(ovqt_plugin_landscape_editor)

View file

@ -0,0 +1,527 @@
// 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).toStdString().c_str());
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();
nlinfo("ligoMove");
//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).toStdString().c_str());
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().toStdString();
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).toStdString().c_str());
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.toStdString());
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
{
return m_landscapeMap.value(m_currentZoneRegion).zoneRegionObject;
}
int ZoneBuilder::countZoneRegion() const
{
return m_landscapeMap.size();
}
ZoneRegionObject *ZoneBuilder::zoneRegion(int id) const
{
return m_landscapeMap.value(id).zoneRegionObject;
}
void ZoneBuilder::ligoData(LigoData &data, const ZonePosition &zonePos)
{
m_landscapeMap.value(zonePos.region).zoneRegionObject->ligoData(data, zonePos.x, zonePos.y);
}
void ZoneBuilder::setLigoData(LigoData &data, const ZonePosition &zonePos)
{
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.toStdString().c_str());
if (!m_zoneBank.addElement((pathName + file).toStdString(), 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 &region = 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 &region = 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 &region = 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 &region = 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(this, m_landscapeScene);
m_undoStack->push(m_undoScanRegionCommand);
}
}
void ZoneBuilder::checkEndMacro()
{
if (m_createdAction)
{
RedoScanRegionCommand *redoScanRegionCommand = new RedoScanRegionCommand(this, m_landscapeScene);
m_undoScanRegionCommand->setScanList(m_zonePositionList);
redoScanRegionCommand->setScanList(m_zonePositionList);
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 false;
}
}
}
return true;
}
} /* namespace LandscapeEditor */

View file

@ -0,0 +1,147 @@
// 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();
/// Init zoneBank and init zone pixmap database
bool init(const QString &pathName, bool displayProgress = false);
void calcMask();
bool getZoneMask (sint32 x, sint32 y);
bool getZoneAmongRegions(ZonePosition &zonePos, BuilderZoneRegion *builderZoneRegionFrom, sint32 x, sint32 y);
/// Ligo Actions
/// @{
void actionLigoTile(const LigoData &data, const ZonePosition &zonePos);
void actionLigoMove(uint index, sint32 deltaX, sint32 deltaY);
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
/// @{
int createZoneRegion();
int createZoneRegion(const QString &fileName);
void deleteZoneRegion(int id);
void setCurrentZoneRegion(int id);
int currentIdZoneRegion() const;
ZoneRegionObject *currentZoneRegion() const;
int countZoneRegion() const;
ZoneRegionObject *zoneRegion(int id) const;
void 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:
/// Scan ./zoneligos dir and add all *.ligozone files to zoneBank
bool initZoneBank (const QString &path);
void checkBeginMacro();
void checkEndMacro();
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

View file

@ -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.toStdString());
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.toStdString().c_str());
if (!m_zoneBank.addElement((pathName + file).toStdString(), 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 &region = 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 */

View file

@ -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 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 LANDSCAPE_EDITOR_EXPORT ZoneBuilderBase
{
public:
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

View file

@ -0,0 +1,100 @@
// 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;
// CZoneRegion contains informations about the zones painted
class BuilderZoneRegion
{
public:
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, void *pInternal = NULL);
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, void *pInt1, void *pInt2);
void putTransitions(sint32 x, sint32 y, const NLLIGO::SPiece &mask, const std::string &matName, void *pInternal);
void updateTrans(sint32 x, sint32 y, NLLIGO::CZoneBankElement *zoneBankElement = NULL);
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);
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

View file

@ -0,0 +1,236 @@
// 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
{
OpenLandscapeCommand::OpenLandscapeCommand(const QString &fileName, QUndoCommand *parent)
: QUndoCommand(parent),
m_fileName(fileName)
{
}
OpenLandscapeCommand::~OpenLandscapeCommand()
{
}
void OpenLandscapeCommand::undo()
{
}
void OpenLandscapeCommand::redo()
{
}
NewLandscapeCommand::NewLandscapeCommand(QUndoCommand *parent)
: QUndoCommand(parent)
{
}
NewLandscapeCommand::~NewLandscapeCommand()
{
}
void NewLandscapeCommand::undo()
{
}
void NewLandscapeCommand::redo()
{
}
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(ZoneBuilder *zoneBuilder, LandscapeScene *scene, QUndoCommand *parent)
: QUndoCommand(parent),
m_zoneBuilder(zoneBuilder),
m_scene(scene)
{
}
UndoScanRegionCommand::~UndoScanRegionCommand()
{
m_zonePositionList.clear();
}
void UndoScanRegionCommand::setScanList(const QList<ZonePosition> &zonePositionList)
{
m_zonePositionList = zonePositionList;
}
void UndoScanRegionCommand::undo()
{
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));
}
}
void UndoScanRegionCommand::redo()
{
}
RedoScanRegionCommand::RedoScanRegionCommand(ZoneBuilder *zoneBuilder, LandscapeScene *scene, QUndoCommand *parent)
: QUndoCommand(parent),
m_zoneBuilder(zoneBuilder),
m_scene(scene)
{
}
RedoScanRegionCommand::~RedoScanRegionCommand()
{
m_zonePositionList.clear();
}
void RedoScanRegionCommand::setScanList(const QList<ZonePosition> &zonePositionList)
{
m_zonePositionList = zonePositionList;
}
void RedoScanRegionCommand::undo()
{
}
void RedoScanRegionCommand::redo()
{
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 &region = 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 */

View file

@ -0,0 +1,156 @@
// 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 OpenLandscapeCommand: public QUndoCommand
{
public:
OpenLandscapeCommand(const QString &fileName, QUndoCommand *parent = 0);
virtual ~OpenLandscapeCommand();
virtual void undo();
virtual void redo();
private:
QString m_fileName;
};
class NewLandscapeCommand: public QUndoCommand
{
public:
NewLandscapeCommand(QUndoCommand *parent = 0);
virtual ~NewLandscapeCommand();
virtual void undo();
virtual void redo();
private:
};
// Modify the landscape
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: public QUndoCommand
{
public:
UndoScanRegionCommand(ZoneBuilder *zoneBuilder, LandscapeScene *scene, QUndoCommand *parent = 0);
virtual ~UndoScanRegionCommand();
void setScanList(const QList<ZonePosition> &zonePositionList);
virtual void undo();
virtual void redo();
private:
QList<ZonePosition> m_zonePositionList;
ZoneBuilder *m_zoneBuilder;
LandscapeScene *m_scene;
};
class RedoScanRegionCommand: public QUndoCommand
{
public:
RedoScanRegionCommand(ZoneBuilder *zoneBuilder, LandscapeScene *scene, QUndoCommand *parent = 0);
virtual ~RedoScanRegionCommand();
void setScanList(const QList<ZonePosition> &zonePositionList);
virtual void undo();
virtual void redo();
private:
QList<ZonePosition> m_zonePositionList;
ZoneBuilder *m_zoneBuilder;
LandscapeScene *m_scene;
};
/*
// Move the landscape
class LigoMoveCommand: public QUndoCommand
{
public:
LigoMoveCommand(int index, sint32 deltaX, sint32 deltaY, ZoneBuilder *zoneBuilder, QUndoCommand *parent = 0);
virtual ~LigoMoveCommand();
virtual void undo();
virtual void redo();
private:
int m_index;
sint32 m_deltaX;
sint32 m_deltaY;
ZoneBuilder *m_zoneBuilder;
};
*/
// Modify the landscape
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

View file

@ -1,5 +1,9 @@
<RCC>
<qresource prefix="/">
<file>icons/ic_nel_zones.png</file>
<file>icons/ic_snapshot.png</file>
<file>icons/ic_grid.png</file>
<file>icons/ic_nel_transition_land.png</file>
<file>icons/ic_nel_landscape_item.png</file>
<file>icons/ic_nel_landscape_settings.png</file>
<file>icons/ic_nel_world_editor.png</file>

View file

@ -22,13 +22,19 @@ namespace LandscapeEditor
{
namespace Constants
{
const char * const LANDSCAPE_EDITOR_PLUGIN = "LandscapeEditor";
const char *const LANDSCAPE_EDITOR_PLUGIN = "LandscapeEditor";
//settings
const char * const LANDSCAPE_EDITOR_SECTION = "LandscapeEditor";
const char *const LANDSCAPE_EDITOR_SECTION = "LandscapeEditor";
const char *const LANDSCAPE_WINDOW_STATE = "LandscapeWindowState";
const char *const LANDSCAPE_WINDOW_GEOMETRY = "LandscapeWindowGeometry";
const char *const LANDSCAPE_DATA_DIRECTORY = "LandscapeDataDirectory";
const char *const LANDSCAPE_USE_OPENGL = "LandscapeUseOpenGL";
//resources
const char * const ICON_LANDSCAPE_ITEM = ":/icons/ic_nel_landscape_item.png";
const char *const ICON_LANDSCAPE_ITEM = ":/icons/ic_nel_landscape_item.png";
const char *const ICON_ZONE_ITEM = ":/icons/ic_nel_zone.png";
const char *const ICON_LANDSCAPE_ZONES = ":/icons/ic_nel_zones.png";
} // namespace Constants

View file

@ -75,7 +75,7 @@ QString LandscapeEditorPlugin::name() const
QString LandscapeEditorPlugin::version() const
{
return "0.0.1";
return "0.1";
}
QString LandscapeEditorPlugin::vendor() const

View file

@ -91,7 +91,7 @@ public:
}
virtual QIcon icon() const
{
return QIcon();
return QIcon(Constants::ICON_LANDSCAPE_ITEM);
}
virtual void open();

View file

@ -18,6 +18,11 @@
// Project includes
#include "landscape_editor_window.h"
#include "landscape_editor_constants.h"
#include "builder_zone.h"
#include "zone_region_editor.h"
#include "landscape_scene.h"
#include "project_settings_dialog.h"
#include "snapshot_dialog.h"
#include "../core/icore.h"
#include "../core/imenu_manager.h"
@ -28,26 +33,78 @@
// Qt includes
#include <QtCore/QSettings>
#include <QtGui/QMenu>
#include <QtGui/QFileDialog>
#include <QtGui/QMessageBox>
#include <QtGui/QStatusBar>
namespace LandscapeEditor
{
static const int LANDSCAPE_ID = 32;
int NewLandCounter = 0;
QString _lastDir;
LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent)
: QMainWindow(parent)
: QMainWindow(parent),
m_currentItem(0),
m_landscapeScene(0),
m_zoneBuilder(0),
m_undoStack(0),
m_oglWidget(0)
{
m_ui.setupUi(this);
m_undoStack = new QUndoStack(this);
m_landscapeScene = new LandscapeScene(160, this);
m_zoneBuilder = new ZoneBuilder(m_landscapeScene, m_ui.zoneListWidget, m_undoStack);
m_ui.zoneListWidget->setZoneBuilder(m_zoneBuilder);
m_ui.zoneListWidget->updateUi();
m_landscapeScene->setZoneBuilder(m_zoneBuilder);
m_ui.graphicsView->setScene(m_landscapeScene);
m_ui.newLandAction->setIcon(QIcon(Core::Constants::ICON_NEW));
m_ui.saveAction->setIcon(QIcon(Core::Constants::ICON_SAVE));
m_ui.saveLandAction->setIcon(QIcon(Core::Constants::ICON_SAVE));
m_ui.saveAsLandAction->setIcon(QIcon(Core::Constants::ICON_SAVE_AS));
m_ui.zonesDockWidget->toggleViewAction()->setIcon(QIcon(Constants::ICON_LANDSCAPE_ZONES));
m_ui.landscapesDockWidget->toggleViewAction()->setIcon(QIcon(Constants::ICON_ZONE_ITEM));
m_ui.deleteLandAction->setEnabled(false);
createMenus();
createToolBars();
readSettings();
connect(m_ui.saveAction, SIGNAL(triggered()), this, SLOT(save()));
connect(m_ui.projectSettingsAction, SIGNAL(triggered()), this, SLOT(openProjectSettings()));
connect(m_ui.snapshotAction, SIGNAL(triggered()), this, SLOT(openSnapshotDialog()));
connect(m_ui.enableGridAction, SIGNAL(toggled(bool)), m_ui.graphicsView, SLOT(setVisibleGrid(bool)));
connect(m_ui.newLandAction, SIGNAL(triggered()), this, SLOT(newLand()));
connect(m_ui.setActiveLandAction, SIGNAL(triggered()), this, SLOT(setActiveLand()));
connect(m_ui.saveLandAction, SIGNAL(triggered()), this, SLOT(saveSelectedLand()));
connect(m_ui.saveAsLandAction, SIGNAL(triggered()), this, SLOT(saveAsSelectedLand()));
connect(m_ui.deleteLandAction, SIGNAL(triggered()), this, SLOT(deleteSelectedLand()));
connect(m_ui.transitionModeAction, SIGNAL(toggled(bool)), m_landscapeScene, SLOT(setTransitionMode(bool)));
connect(m_ui.landscapesListWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(customContextMenu()));
m_ui.landscapesListWidget->setContextMenuPolicy(Qt::CustomContextMenu);
m_statusBarTimer = new QTimer(this);
connect(m_statusBarTimer, SIGNAL(timeout()), this, SLOT(updateStatusBar()));
m_statusInfo = new QLabel(this);
m_statusInfo->hide();
Core::ICore::instance()->mainWindow()->statusBar()->addPermanentWidget(m_statusInfo);
}
LandscapeEditorWindow::~LandscapeEditorWindow()
{
writeSettings();
delete m_zoneBuilder;
}
QUndoStack *LandscapeEditorWindow::undoStack() const
@ -66,19 +123,281 @@ void LandscapeEditorWindow::open()
{
QStringList list = fileNames;
_lastDir = QFileInfo(list.front()).absolutePath();
Q_FOREACH(QString fileName, fileNames)
{
int row = createLandscape(fileName);
if (row != -1)
setActiveLandscape(row);
}
}
setCursor(Qt::ArrowCursor);
}
void LandscapeEditorWindow::save()
{
saveLandscape(m_ui.landscapesListWidget->row(m_currentItem), true);
}
void LandscapeEditorWindow::openProjectSettings()
{
ProjectSettingsDialog *dialog = new ProjectSettingsDialog(m_zoneBuilder->dataPath(), this);
dialog->show();
int ok = dialog->exec();
if (ok == QDialog::Accepted)
{
m_zoneBuilder->init(dialog->dataPath(), true);
m_ui.zoneListWidget->updateUi();
}
delete dialog;
}
void LandscapeEditorWindow::openSnapshotDialog()
{
SnapshotDialog *dialog = new SnapshotDialog(this);
dialog->show();
int ok = dialog->exec();
if (ok == QDialog::Accepted)
{
QString fileName = QFileDialog::getSaveFileName(this,
tr("Save screenshot landscape"), _lastDir,
tr("Image file (*.png)"));
setCursor(Qt::WaitCursor);
NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->currentZoneRegion()->ligoZoneRegion();
sint32 regionMinX = zoneRegion.getMinX();
sint32 regionMaxX = zoneRegion.getMaxX();
sint32 regionMinY = zoneRegion.getMinY();
sint32 regionMaxY = zoneRegion.getMaxY();
int regionWidth = (regionMaxX - regionMinX + 1);
int regionHeight = (regionMaxY - regionMinY + 1);
int cellSize = m_landscapeScene->cellSize();
QRectF rect(regionMinX * cellSize, abs(regionMaxY) * cellSize, regionWidth * cellSize, regionHeight * cellSize);
if (dialog->isCustomSize())
{
int widthSnapshot = dialog->widthSnapshot();
int heightSnapshot = dialog->heightSnapshot();
if (dialog->isKeepRatio())
heightSnapshot = (widthSnapshot / regionWidth) * regionHeight;
m_landscapeScene->snapshot(fileName, widthSnapshot, heightSnapshot, rect);
}
else
{
m_landscapeScene->snapshot(fileName, regionWidth * dialog->resolutionZone(),
regionHeight * dialog->resolutionZone(), rect);
}
setCursor(Qt::ArrowCursor);
}
delete dialog;
}
void LandscapeEditorWindow::customContextMenu()
{
if (m_ui.landscapesListWidget->currentRow() == -1)
return;
QMenu *popurMenu = new QMenu(this);
popurMenu->addAction(m_ui.setActiveLandAction);
popurMenu->addAction(m_ui.saveLandAction);
popurMenu->addAction(m_ui.saveAsLandAction);
popurMenu->addAction(m_ui.deleteLandAction);
popurMenu->exec(QCursor::pos());
delete popurMenu;
}
void LandscapeEditorWindow::newLand()
{
int row = createLandscape(QString());
if (row != -1)
setActiveLandscape(row);
}
void LandscapeEditorWindow::setActiveLand()
{
setActiveLandscape(m_ui.landscapesListWidget->currentRow());
}
void LandscapeEditorWindow::saveSelectedLand()
{
saveLandscape(m_ui.landscapesListWidget->currentRow(), true);
}
void LandscapeEditorWindow::saveAsSelectedLand()
{
saveLandscape(m_ui.landscapesListWidget->currentRow(), false);
}
void LandscapeEditorWindow::deleteSelectedLand()
{
int row = m_ui.landscapesListWidget->currentRow();
int current_row = m_ui.landscapesListWidget->row(m_currentItem);
QListWidgetItem *item = m_ui.landscapesListWidget->item(row);
if (row == current_row)
{
if (row == 0)
++row;
else
--row;
setActiveLandscape(row);
}
m_zoneBuilder->deleteZoneRegion(item->data(LANDSCAPE_ID).toInt());
m_ui.landscapesListWidget->removeItemWidget(item);
delete item;
if (m_ui.landscapesListWidget->count() == 1)
m_ui.deleteLandAction->setEnabled(false);
m_undoStack->clear();
}
int LandscapeEditorWindow::createLandscape(const QString &fileName)
{
int id;
if (fileName.isEmpty())
id = m_zoneBuilder->createZoneRegion();
else
id = m_zoneBuilder->createZoneRegion(fileName);
if (id == -1)
{
QMessageBox::critical(this, "Landscape Editor", "Cannot add this zone because it overlaps existing ones");
return -1;
}
ZoneRegionObject *zoneRegion = m_zoneBuilder->zoneRegion(id);
m_ui.graphicsView->centerOn(zoneRegion->ligoZoneRegion().getMinX() * m_landscapeScene->cellSize(),
abs(zoneRegion->ligoZoneRegion().getMinY()) * m_landscapeScene->cellSize());
QListWidgetItem *item;
if (fileName.isEmpty())
item = new QListWidgetItem(QString("NewLandscape%1").arg(NewLandCounter++), m_ui.landscapesListWidget);
else
item = new QListWidgetItem(fileName, m_ui.landscapesListWidget);
item->setData(LANDSCAPE_ID, id);
item->setFont(QFont("SansSerif", 9, QFont::Normal));
if (m_ui.landscapesListWidget->count() > 1)
m_ui.deleteLandAction->setEnabled(true);
return m_ui.landscapesListWidget->count() - 1;
}
void LandscapeEditorWindow::setActiveLandscape(int row)
{
if ((0 <= row) && (row < m_ui.landscapesListWidget->count()))
{
if (m_currentItem != 0)
m_currentItem->setFont(QFont("SansSerif", 9, QFont::Normal));
QListWidgetItem *item = m_ui.landscapesListWidget->item(row);
item->setFont(QFont("SansSerif", 9, QFont::Bold));
m_zoneBuilder->setCurrentZoneRegion(item->data(LANDSCAPE_ID).toInt());
m_currentItem = item;
}
}
void LandscapeEditorWindow::saveLandscape(int row, bool force)
{
if ((0 <= row) && (row < m_ui.landscapesListWidget->count()))
{
QListWidgetItem *item = m_ui.landscapesListWidget->item(row);
ZoneRegionObject *regionObject = m_zoneBuilder->zoneRegion(item->data(LANDSCAPE_ID).toInt());
if ((!force) || (regionObject->fileName().empty()))
{
QString fileName = QFileDialog::getSaveFileName(this,
tr("Save NeL Ligo land file"), _lastDir,
tr("NeL Ligo land file (*.land)"));
if (!fileName.isEmpty())
{
regionObject->setFileName(fileName.toStdString());
regionObject->save();
regionObject->setModified(false);
item->setText(fileName);
}
}
else
{
regionObject->save();
regionObject->setModified(false);
}
}
}
void LandscapeEditorWindow::showEvent(QShowEvent *showEvent)
{
QMainWindow::showEvent(showEvent);
if (m_oglWidget != 0)
m_oglWidget->makeCurrent();
m_statusInfo->show();
m_statusBarTimer->start(100);
}
void LandscapeEditorWindow::hideEvent(QHideEvent *hideEvent)
{
QMainWindow::hideEvent(hideEvent);
m_statusInfo->hide();
m_statusBarTimer->stop();
}
void LandscapeEditorWindow::updateStatusBar()
{
m_statusInfo->setText(m_landscapeScene->zoneNameFromMousePos());
}
void LandscapeEditorWindow::createMenus()
{
Core::IMenuManager *menuManager = Core::ICore::instance()->menuManager();
}
void LandscapeEditorWindow::createToolBars()
{
Core::IMenuManager *menuManager = Core::ICore::instance()->menuManager();
//QAction *action = menuManager->action(Core::Constants::NEW);
//m_ui.fileToolBar->addAction(action);
//action = menuManager->action(Core::Constants::SAVE);
//m_ui.fileToolBar->addAction(action);
//action = menuManager->action(Core::Constants::SAVE_AS);
//m_ui.fileToolBar->addAction(action);
QAction *action = menuManager->action(Core::Constants::OPEN);
m_ui.fileToolBar->addAction(m_ui.newLandAction);
m_ui.fileToolBar->addAction(action);
m_ui.fileToolBar->addAction(m_ui.saveAction);
m_ui.fileToolBar->addSeparator();
action = menuManager->action(Core::Constants::UNDO);
if (action != 0)
m_ui.fileToolBar->addAction(action);
action = menuManager->action(Core::Constants::REDO);
if (action != 0)
m_ui.fileToolBar->addAction(action);
m_ui.zoneToolBar->insertAction(m_ui.enableGridAction, m_ui.landscapesDockWidget->toggleViewAction());
m_ui.zoneToolBar->insertAction(m_ui.enableGridAction, m_ui.zonesDockWidget->toggleViewAction());
}
void LandscapeEditorWindow::readSettings()
{
QSettings *settings = Core::ICore::instance()->settings();
settings->beginGroup(Constants::LANDSCAPE_EDITOR_SECTION);
restoreState(settings->value(Constants::LANDSCAPE_WINDOW_STATE).toByteArray());
restoreGeometry(settings->value(Constants::LANDSCAPE_WINDOW_GEOMETRY).toByteArray());
// Read landscape data directory (contains sub-paths: zone logos, zone bitmaps)
m_zoneBuilder->init(settings->value(Constants::LANDSCAPE_DATA_DIRECTORY).toString());
m_ui.zoneListWidget->updateUi();
// Use OpenGL graphics system instead raster graphics system
if (settings->value(Constants::LANDSCAPE_USE_OPENGL, false).toBool())
{
m_oglWidget = new QGLWidget(QGLFormat(QGL::DoubleBuffer));
m_ui.graphicsView->setViewport(m_oglWidget);
}
settings->endGroup();
}
@ -86,6 +405,9 @@ void LandscapeEditorWindow::writeSettings()
{
QSettings *settings = Core::ICore::instance()->settings();
settings->beginGroup(Constants::LANDSCAPE_EDITOR_SECTION);
settings->setValue(Constants::LANDSCAPE_WINDOW_STATE, saveState());
settings->setValue(Constants::LANDSCAPE_WINDOW_GEOMETRY, saveGeometry());
settings->setValue(Constants::LANDSCAPE_DATA_DIRECTORY, m_zoneBuilder->dataPath());
settings->endGroup();
settings->sync();
}

View file

@ -23,10 +23,16 @@
// Qt includes
#include <QtGui/QUndoStack>
#include <QtOpenGL/QGLWidget>
#include <QtGui/QLabel>
#include <QtCore/QTimer>
namespace LandscapeEditor
{
class LandscapeScene;
class ZoneBuilder;
class LandscapeEditorWindow: public QMainWindow
{
Q_OBJECT
@ -40,14 +46,41 @@ public:
Q_SIGNALS:
public Q_SLOTS:
void open();
void save();
private Q_SLOTS:
void openProjectSettings();
void openSnapshotDialog();
void customContextMenu();
void updateStatusBar();
void newLand();
void setActiveLand();
void saveSelectedLand();
void saveAsSelectedLand();
void deleteSelectedLand();
protected:
virtual void showEvent(QShowEvent *showEvent);
virtual void hideEvent(QHideEvent *hideEvent);
private:
void createMenus();
void createToolBars();
void readSettings();
void writeSettings();
void setActiveLandscape(int row);
void saveLandscape(int row, bool force);
int createLandscape(const QString &fileName);
QLabel *m_statusInfo;
QTimer *m_statusBarTimer;
QListWidgetItem *m_currentItem;
LandscapeScene *m_landscapeScene;
ZoneBuilder *m_zoneBuilder;
QUndoStack *m_undoStack;
QGLWidget *m_oglWidget;
Ui::LandscapeEditorWindow m_ui;
}; /* class LandscapeEditorWindow */

View file

@ -19,12 +19,42 @@
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QGridLayout" name="gridLayout">
<property name="margin">
<number>3</number>
</property>
<property name="spacing">
<number>3</number>
</property>
<item row="0" column="0">
<widget class="QGraphicsView" name="graphicsView"/>
<widget class="LandscapeEditor::LandscapeView" name="graphicsView">
<property name="sceneRect">
<rectf>
<x>0.000000000000000</x>
<y>0.000000000000000</y>
<width>0.000000000000000</width>
<height>0.000000000000000</height>
</rectf>
</property>
<property name="dragMode">
<enum>QGraphicsView::NoDrag</enum>
</property>
<property name="transformationAnchor">
<enum>QGraphicsView::AnchorUnderMouse</enum>
</property>
<property name="resizeAnchor">
<enum>QGraphicsView::AnchorUnderMouse</enum>
</property>
<property name="viewportUpdateMode">
<enum>QGraphicsView::FullViewportUpdate</enum>
</property>
<property name="optimizationFlags">
<set>QGraphicsView::DontSavePainterState</set>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QToolBar" name="toolBar">
<widget class="QToolBar" name="fileToolBar">
<property name="windowTitle">
<string>toolBar</string>
</property>
@ -35,7 +65,177 @@
<bool>false</bool>
</attribute>
</widget>
<widget class="QDockWidget" name="zonesDockWidget">
<property name="windowIcon">
<iconset resource="landscape_editor.qrc">
<normaloff>:/icons/ic_nel_zones.png</normaloff>:/icons/ic_nel_zones.png</iconset>
</property>
<property name="windowTitle">
<string>Zones</string>
</property>
<attribute name="dockWidgetArea">
<number>2</number>
</attribute>
<widget class="LandscapeEditor::ListZonesWidget" name="zoneListWidget"/>
</widget>
<widget class="QDockWidget" name="landscapesDockWidget">
<property name="windowIcon">
<iconset resource="landscape_editor.qrc">
<normaloff>:/icons/ic_nel_zone.png</normaloff>:/icons/ic_nel_zone.png</iconset>
</property>
<property name="windowTitle">
<string>Landscapes</string>
</property>
<attribute name="dockWidgetArea">
<number>1</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents">
<layout class="QGridLayout" name="gridLayout_2">
<property name="margin">
<number>3</number>
</property>
<property name="spacing">
<number>3</number>
</property>
<item row="0" column="0">
<widget class="QListWidget" name="landscapesListWidget"/>
</item>
</layout>
</widget>
</widget>
<widget class="QToolBar" name="zoneToolBar">
<property name="windowTitle">
<string>toolBar</string>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
<addaction name="transitionModeAction"/>
<addaction name="enableGridAction"/>
<addaction name="projectSettingsAction"/>
<addaction name="snapshotAction"/>
</widget>
<action name="projectSettingsAction">
<property name="icon">
<iconset resource="landscape_editor.qrc">
<normaloff>:/icons/ic_nel_landscape_settings.png</normaloff>:/icons/ic_nel_landscape_settings.png</iconset>
</property>
<property name="text">
<string>Project settings</string>
</property>
</action>
<action name="enableGridAction">
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="landscape_editor.qrc">
<normaloff>:/icons/ic_grid.png</normaloff>:/icons/ic_grid.png</iconset>
</property>
<property name="text">
<string>EnableGrid</string>
</property>
<property name="toolTip">
<string>Show/Hide Grid</string>
</property>
<property name="shortcut">
<string>Ctrl+G</string>
</property>
</action>
<action name="snapshotAction">
<property name="icon">
<iconset resource="landscape_editor.qrc">
<normaloff>:/icons/ic_snapshot.png</normaloff>:/icons/ic_snapshot.png</iconset>
</property>
<property name="text">
<string>snapshot</string>
</property>
</action>
<action name="saveAction">
<property name="text">
<string>Save</string>
</property>
</action>
<action name="setActiveLandAction">
<property name="icon">
<iconset resource="landscape_editor.qrc">
<normaloff>:/icons/ic_nel_zone.png</normaloff>:/icons/ic_nel_zone.png</iconset>
</property>
<property name="text">
<string>Set active</string>
</property>
<property name="toolTip">
<string>Set active selected landscape</string>
</property>
</action>
<action name="saveLandAction">
<property name="text">
<string>Save</string>
</property>
<property name="toolTip">
<string>Save selected landscape</string>
</property>
</action>
<action name="saveAsLandAction">
<property name="text">
<string>Save As landscape</string>
</property>
<property name="toolTip">
<string>Save as selected landscape</string>
</property>
</action>
<action name="deleteLandAction">
<property name="text">
<string>Delete</string>
</property>
<property name="toolTip">
<string>Delete selected landscape</string>
</property>
</action>
<action name="newLandAction">
<property name="text">
<string>New</string>
</property>
<property name="toolTip">
<string>Create new landscape</string>
</property>
</action>
<action name="transitionModeAction">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="landscape_editor.qrc">
<normaloff>:/icons/ic_nel_landscape_item.png</normaloff>
<normalon>:/icons/ic_nel_transition_land.png</normalon>:/icons/ic_nel_landscape_item.png</iconset>
</property>
<property name="text">
<string>Transition mode</string>
</property>
<property name="toolTip">
<string>Enable transition mode</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>
<class>LandscapeEditor::ListZonesWidget</class>
<extends>QWidget</extends>
<header>list_zones_widget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>LandscapeEditor::LandscapeView</class>
<extends>QGraphicsView</extends>
<header>landscape_view.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="landscape_editor.qrc"/>
</resources>

View file

@ -0,0 +1,518 @@
// 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);
/*
// Render debug text (slow!)
painter->setPen(QPen(Qt::white, 0.5, Qt::SolidLine));
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));
for (int i = left; i < right; ++i)
{
for (int j = top; j < bottom; ++j)
{
LigoData data;
m_zoneBuilder->currentZoneRegion()->ligoData(data, i, -j);
painter->drawText(i * m_cellSize + 10, j * m_cellSize + 10, QString("%1 %2 %3 %4").arg(i).arg(j).arg(data.posX).arg(data.posY));
}
}
*/
}
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 */

View file

@ -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

View file

@ -0,0 +1,324 @@
// 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)
{
QGraphicsItem *item = itemAt(zonePos.x * m_cellSize, abs(zonePos.y) * m_cellSize);
// TODO: delete LAYER_BLACKOUT_NAME
if ((item != 0) && (item->data(ZONE_NAME).toString() != QString(LAYER_BLACKOUT_NAME)))
{
removeItem(item);
delete item;
}
}
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).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));
m_mouseButton = mouseEvent->button();
}
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);
}
void LandscapeSceneBase::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
QGraphicsScene::mouseReleaseEvent(mouseEvent);
m_mouseButton = Qt::NoButton;
}
bool LandscapeSceneBase::checkUnderZone(const int posX, const int posY)
{
// TODO: it will not work correctly in world editor
QGraphicsItem *item = itemAt((posX * m_cellSize), abs(posY) * m_cellSize);
if (item != 0)
return true;
return false;
}
} /* namespace LandscapeEditor */

View file

@ -0,0 +1,81 @@
// 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);
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent);
private:
bool checkUnderZone(const int posX, const int posY);
int m_cellSize;
qreal m_mouseX, m_mouseY;
sint32 m_posX, m_posY;
Qt::MouseButton m_mouseButton;
ZoneBuilderBase *m_zoneBuilderBase;
};
} /* namespace LandscapeEditor */
#endif // LANDSCAPE_SCENE_BASE_H

View file

@ -0,0 +1,180 @@
// 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),
m_moveMouse(false)
{
//setDragMode(ScrollHandDrag);
setTransformationAnchor(AnchorUnderMouse);
setBackgroundBrush(QBrush(Qt::lightGray));
//setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);
//setRenderHints(QPainter::Antialiasing);
//setCacheMode(QGraphicsView::CacheBackground);
m_cellSize = 160;
m_numSteps = 0;
m_maxSteps = 20;
}
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)
{
double numDegrees = event->delta() / 8.0;
double numSteps = numDegrees / 15.0;
double factor = std::pow(1.125, numSteps);
if (factor > 1.0)
{
// check max scale view
if (m_numSteps > m_maxSteps)
return;
++m_numSteps;
}
else
{
// check min scale view
if (m_numSteps < -m_maxSteps)
return;
--m_numSteps;
}
scale(factor, factor);
QGraphicsView::wheelEvent(event);
}
void LandscapeView::mousePressEvent(QMouseEvent *event)
{
QGraphicsView::mousePressEvent(event);
if (event->button() != Qt::MiddleButton)
return;
m_moveMouse = true;
QApplication::setOverrideCursor(Qt::ClosedHandCursor);
}
void LandscapeView::mouseMoveEvent(QMouseEvent *event)
{
if (m_moveMouse)
translate(0.001, 0.001);
QGraphicsView::mouseMoveEvent(event);
}
void LandscapeView::mouseReleaseEvent(QMouseEvent *event)
{
QApplication::restoreOverrideCursor();
m_moveMouse = false;
QGraphicsView::mouseReleaseEvent(event);
}
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 (m_numSteps > -m_maxSteps / 4)
{
painter->setPen(QPen(Qt::white, 0.5, Qt::SolidLine));
//painter->setFont(QFont("Helvetica [Cronyx]", 12));
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 */

View file

@ -0,0 +1,64 @@
// 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 LANDSCAPE_EDITOR_EXPORT LandscapeView: public QGraphicsView
{
Q_OBJECT
public:
LandscapeView(QWidget *parent = 0);
virtual ~LandscapeView();
bool isVisibleGrid() const;
public Q_SLOTS:
void setVisibleGrid(bool visible);
void setVisibleText(bool visible);
private Q_SLOTS:
protected:
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);
void drawGrid(QPainter *painter, const QRectF &rect);
void drawZoneNames(QPainter *painter, const QRectF &rect);
private:
bool m_visibleGrid, m_visibleText;
int m_numSteps, m_maxSteps;
int m_cellSize;
bool m_moveMouse;
}; /* class LandscapeView */
} /* namespace LandscapeEditor */
#endif // LANDSCAPE_VIEW_H

View file

@ -0,0 +1,139 @@
// 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 /* 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.toStdString().c_str());
else
result = m_pixmapMap.value(zoneName);
return result;
}
} /* namespace LandscapeEditor */

View file

@ -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 contains the small images for QListView
@details
*/
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);
/// Unload all 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

View file

@ -0,0 +1,308 @@
// 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_widget.h"
#include "list_zones_model.h"
#include "builder_zone.h"
// NeL includes
#include <nel/misc/debug.h>
#include <nel/ligo/zone_bank.h>
#include <nel/ligo/zone_region.h>
// STL includes
#include <vector>
#include <string>
// Qt includes
#include <QtGui/QIcon>
#include <QtCore/QModelIndex>
namespace LandscapeEditor
{
ListZonesWidget::ListZonesWidget(QWidget *parent)
: QWidget(parent),
m_rotCycle(0),
m_flipCycle(0),
m_listZonesModel(0),
m_zoneBuilder(0)
{
m_ui.setupUi(this);
m_listZonesModel = new ListZonesModel(4, this);
m_ui.listView->setModel(m_listZonesModel);
m_ui.addFilterButton_1->setChecked(false);
m_ui.addFilterButton_2->setChecked(false);
m_ui.addFilterButton_3->setChecked(false);
connect(m_ui.categoryTypeComboBox_1, SIGNAL(currentIndexChanged(QString)), this, SLOT(updateFilters_1(QString)));
connect(m_ui.categoryTypeComboBox_2, SIGNAL(currentIndexChanged(QString)), this, SLOT(updateFilters_2(QString)));
connect(m_ui.categoryTypeComboBox_3, SIGNAL(currentIndexChanged(QString)), this, SLOT(updateFilters_3(QString)));
connect(m_ui.categoryTypeComboBox_4, SIGNAL(currentIndexChanged(QString)), this, SLOT(updateFilters_4(QString)));
connect(m_ui.categoryValueComboBox_1, SIGNAL(currentIndexChanged(int)), this, SLOT(updateListZones()));
connect(m_ui.categoryValueComboBox_2, SIGNAL(currentIndexChanged(int)), this, SLOT(updateListZones()));
connect(m_ui.categoryValueComboBox_3, SIGNAL(currentIndexChanged(int)), this, SLOT(updateListZones()));
connect(m_ui.categoryValueComboBox_4, SIGNAL(currentIndexChanged(int)), this, SLOT(updateListZones()));
connect(m_ui.logicComboBox_2, SIGNAL(currentIndexChanged(int)), this, SLOT(updateListZones()));
connect(m_ui.logicComboBox_3, SIGNAL(currentIndexChanged(int)), this, SLOT(updateListZones()));
connect(m_ui.logicComboBox_4, SIGNAL(currentIndexChanged(int)), this, SLOT(updateListZones()));
}
ListZonesWidget::~ListZonesWidget()
{
}
void ListZonesWidget::updateUi()
{
if (m_zoneBuilder == 0)
return;
disableSignals(true);
std::vector<std::string> listCategoryType;
m_zoneBuilder->getZoneBank().getCategoriesType(listCategoryType);
QStringList listCategories;
listCategories << STRING_UNUSED;
for (size_t i = 0; i < listCategoryType.size(); ++i)
listCategories << QString(listCategoryType[i].c_str());
m_ui.categoryTypeComboBox_1->clear();
m_ui.categoryTypeComboBox_2->clear();
m_ui.categoryTypeComboBox_3->clear();
m_ui.categoryTypeComboBox_4->clear();
m_ui.categoryValueComboBox_1->clear();
m_ui.categoryValueComboBox_2->clear();
m_ui.categoryValueComboBox_3->clear();
m_ui.categoryValueComboBox_4->clear();
m_ui.categoryTypeComboBox_1->addItems(listCategories);
m_ui.categoryTypeComboBox_2->addItems(listCategories);
m_ui.categoryTypeComboBox_3->addItems(listCategories);
m_ui.categoryTypeComboBox_4->addItems(listCategories);
disableSignals(false);
m_listZonesModel->rebuildModel(m_zoneBuilder->pixmapDatabase());
}
QString ListZonesWidget::currentZoneName()
{
QString zoneName = "";
QModelIndex index = m_ui.listView->currentIndex();
if (index.isValid())
zoneName = index.data().toString();
if (m_ui.zoneSelectComboBox->currentIndex() == 1)
{
// Random value
if (m_listSelection.size() > 0)
{
uint32 randZone = uint32(NLMISC::frand(m_listSelection.size()));
NLMISC::clamp(randZone, (uint32)0, uint32(m_listSelection.size() - 1));
zoneName = m_listSelection[randZone];
}
}
else if (m_ui.zoneSelectComboBox->currentIndex() == 2)
{
// Full cycle
if (m_listSelection.size() > 0)
{
zoneName = m_listSelection[m_zoneNameCycle];
m_zoneNameCycle++;
m_zoneNameCycle = m_zoneNameCycle % m_listSelection.size();
}
}
return zoneName;
}
int ListZonesWidget::currentRot()
{
int rot = m_ui.rotComboBox->currentIndex();
if (rot == 4)
{
// Random value
uint32 randRot = uint32(NLMISC::frand(4.0));
NLMISC::clamp(randRot, (uint32)0, (uint32)3);
rot = int(randRot);
}
else if (rot == 5)
{
// Full cycle
rot = m_rotCycle;
m_rotCycle++;
m_rotCycle = m_rotCycle % 4;
}
return rot;
}
int ListZonesWidget::currentFlip()
{
int flip = m_ui.flipComboBox->currentIndex();
if (flip == 2)
{
// Random value
uint32 randFlip = uint32(NLMISC::frand(2.0));
NLMISC::clamp (randFlip, (uint32)0, (uint32)1);
flip = int(randFlip);
}
else if (flip == 3)
{
// Full cycle
flip = m_flipCycle;
m_flipCycle++;
m_flipCycle = m_flipCycle % 2;
}
return flip;
}
bool ListZonesWidget::isNotPropogate() const
{
return m_ui.propogateCheckBox->isChecked();
}
bool ListZonesWidget::isForce() const
{
return m_ui.forceCheckBox->isChecked();
}
void ListZonesWidget::setZoneBuilder(ZoneBuilder *zoneBuilder)
{
m_zoneBuilder = zoneBuilder;
}
void ListZonesWidget::updateFilters_1(const QString &value)
{
disableSignals(true);
std::vector<std::string> allCategoryValues;
m_zoneBuilder->getZoneBank().getCategoryValues(value.toStdString(), allCategoryValues);
m_ui.categoryValueComboBox_1->clear();
for(size_t i = 0; i < allCategoryValues.size(); ++i)
m_ui.categoryValueComboBox_1->addItem(QString(allCategoryValues[i].c_str()));
disableSignals(false);
updateListZones();
}
void ListZonesWidget::updateFilters_2(const QString &value)
{
disableSignals(true);
std::vector<std::string> allCategoryValues;
m_zoneBuilder->getZoneBank().getCategoryValues(value.toStdString(), allCategoryValues);
m_ui.categoryValueComboBox_2->clear();
for(size_t i = 0; i < allCategoryValues.size(); ++i)
m_ui.categoryValueComboBox_2->addItem(QString(allCategoryValues[i].c_str()));
disableSignals(false);
updateListZones();
}
void ListZonesWidget::updateFilters_3(const QString &value)
{
disableSignals(true);
std::vector<std::string> allCategoryValues;
m_zoneBuilder->getZoneBank().getCategoryValues(value.toStdString(), allCategoryValues);
m_ui.categoryValueComboBox_3->clear();
for(size_t i = 0; i < allCategoryValues.size(); ++i)
m_ui.categoryValueComboBox_3->addItem(QString(allCategoryValues[i].c_str()));
disableSignals(false);
updateListZones();
}
void ListZonesWidget::updateFilters_4(const QString &value)
{
disableSignals(true);
std::vector<std::string> allCategoryValues;
m_zoneBuilder->getZoneBank().getCategoryValues(value.toStdString(), allCategoryValues);
m_ui.categoryValueComboBox_4->clear();
for(size_t i = 0; i < allCategoryValues.size(); ++i)
m_ui.categoryValueComboBox_4->addItem(QString(allCategoryValues[i].c_str()));
disableSignals(false);
updateListZones();
}
void ListZonesWidget::updateListZones()
{
// Execute the filter
NLLIGO::CZoneBank &zoneBank = m_zoneBuilder->getZoneBank();
zoneBank.resetSelection ();
if(m_ui.categoryTypeComboBox_1->currentIndex() > 0 )
zoneBank.addOrSwitch (m_ui.categoryTypeComboBox_1->currentText().toStdString()
, m_ui.categoryValueComboBox_1->currentText().toStdString());
if(m_ui.categoryTypeComboBox_2->currentIndex() > 0 )
{
if (m_ui.logicComboBox_2->currentIndex() == 0) // AND switch wanted
zoneBank.addAndSwitch(m_ui.categoryTypeComboBox_2->currentText().toStdString()
,m_ui.categoryValueComboBox_2->currentText().toStdString());
else // OR switch wanted
zoneBank.addOrSwitch(m_ui.categoryTypeComboBox_2->currentText().toStdString()
,m_ui.categoryValueComboBox_2->currentText().toStdString());
}
if(m_ui.categoryTypeComboBox_3->currentIndex() > 0 )
{
if (m_ui.logicComboBox_3->currentIndex() == 0) // AND switch wanted
zoneBank.addAndSwitch(m_ui.categoryTypeComboBox_3->currentText().toStdString()
,m_ui.categoryValueComboBox_3->currentText().toStdString());
else // OR switch wanted
zoneBank.addOrSwitch(m_ui.categoryTypeComboBox_3->currentText().toStdString()
,m_ui.categoryValueComboBox_3->currentText().toStdString());
}
if(m_ui.categoryTypeComboBox_4->currentIndex() > 0 )
{
if (m_ui.logicComboBox_4->currentIndex() == 0) // AND switch wanted
zoneBank.addAndSwitch(m_ui.categoryTypeComboBox_4->currentText().toStdString()
,m_ui.categoryValueComboBox_4->currentText().toStdString());
else // OR switch wanted
zoneBank.addOrSwitch(m_ui.categoryTypeComboBox_4->currentText().toStdString()
,m_ui.categoryValueComboBox_4->currentText().toStdString());
}
std::vector<NLLIGO::CZoneBankElement *> currentSelection;
zoneBank.getSelection (currentSelection);
m_listSelection.clear();
m_zoneNameCycle = 0;
for (size_t i = 0; i < currentSelection.size(); ++i)
m_listSelection << currentSelection[i]->getName().c_str();
m_listZonesModel->setListZones(m_listSelection);
}
void ListZonesWidget::disableSignals(bool block)
{
m_ui.categoryTypeComboBox_1->blockSignals(block);
m_ui.categoryTypeComboBox_2->blockSignals(block);
m_ui.categoryTypeComboBox_3->blockSignals(block);
m_ui.categoryTypeComboBox_4->blockSignals(block);
m_ui.categoryValueComboBox_1->blockSignals(block);
m_ui.categoryValueComboBox_2->blockSignals(block);
m_ui.categoryValueComboBox_3->blockSignals(block);
m_ui.categoryValueComboBox_4->blockSignals(block);
}
} /* namespace LandscapeEditor */

View file

@ -0,0 +1,84 @@
// 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_WIDGET_H
#define LIST_ZONES_WIDGET_H
// Project includes
#include "ui_list_zones_widget.h"
// NeL includes
// Qt includes
namespace LandscapeEditor
{
class ListZonesModel;
class ZoneBuilder;
/**
@class ZoneListWidget
@brief ZoneListWidget displays list available zones in accordance with the filter settings
@details
*/
class ListZonesWidget: public QWidget
{
Q_OBJECT
public:
ListZonesWidget(QWidget *parent = 0);
~ListZonesWidget();
void updateUi();
// Set zone builder, call this method before using this class
void setZoneBuilder(ZoneBuilder *zoneBuilder);
// Get current zone name which user selected from list.
QString currentZoneName();
// Get current rotation value which user selected (Rot 0-0deg, 1-90deg, 2-180deg, 3-270deg).
int currentRot();
// Get current flip value which user selected (Flip 0-false, 1-true).
int currentFlip();
bool isNotPropogate() const;
bool isForce() const;
private Q_SLOTS:
void updateFilters_1(const QString &value);
void updateFilters_2(const QString &value);
void updateFilters_3(const QString &value);
void updateFilters_4(const QString &value);
void updateListZones();
private:
void disableSignals(bool block);
int m_rotCycle, m_flipCycle;
int m_zoneNameCycle;
QStringList m_listSelection;
ListZonesModel *m_listZonesModel;
ZoneBuilder *m_zoneBuilder;
Ui::ListZonesWidget m_ui;
}; /* ZoneListWidget */
} /* namespace LandscapeEditor */
#endif // LIST_ZONES_WIDGET_H

View file

@ -0,0 +1,493 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ListZonesWidget</class>
<widget class="QWidget" name="ListZonesWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>359</width>
<height>579</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<property name="margin">
<number>3</number>
</property>
<property name="spacing">
<number>3</number>
</property>
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Filter</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<property name="margin">
<number>6</number>
</property>
<property name="spacing">
<number>3</number>
</property>
<item row="0" column="1">
<widget class="QComboBox" name="categoryTypeComboBox_1"/>
</item>
<item row="0" column="2">
<widget class="QComboBox" name="categoryValueComboBox_1"/>
</item>
<item row="0" column="3">
<widget class="QComboBox" name="zoneSelectComboBox">
<item>
<property name="text">
<string>Select</string>
</property>
</item>
<item>
<property name="text">
<string>Random</string>
</property>
</item>
<item>
<property name="text">
<string>Fyll cycle</string>
</property>
</item>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="categoryTypeComboBox_2">
<property name="enabled">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QComboBox" name="categoryValueComboBox_2">
<property name="enabled">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QComboBox" name="logicComboBox_2">
<property name="enabled">
<bool>true</bool>
</property>
<item>
<property name="text">
<string>And</string>
</property>
</item>
<item>
<property name="text">
<string>Or</string>
</property>
</item>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="categoryTypeComboBox_3">
<property name="enabled">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QComboBox" name="categoryValueComboBox_3">
<property name="enabled">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QComboBox" name="logicComboBox_3">
<property name="enabled">
<bool>true</bool>
</property>
<item>
<property name="text">
<string>And</string>
</property>
</item>
<item>
<property name="text">
<string>Or</string>
</property>
</item>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="categoryTypeComboBox_4">
<property name="enabled">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QComboBox" name="categoryValueComboBox_4">
<property name="enabled">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="3">
<widget class="QComboBox" name="logicComboBox_4">
<property name="enabled">
<bool>true</bool>
</property>
<item>
<property name="text">
<string>And</string>
</property>
</item>
<item>
<property name="text">
<string>Or</string>
</property>
</item>
</widget>
</item>
<item row="0" column="0">
<widget class="QToolButton" name="addFilterButton_1">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../core/core.qrc">
<normaloff>:/core/icons/ic_nel_add_item.png</normaloff>
<normalon>:/core/icons/ic_nel_delete_item.png</normalon>:/core/icons/ic_nel_add_item.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QToolButton" name="addFilterButton_2">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../core/core.qrc">
<normaloff>:/core/icons/ic_nel_add_item.png</normaloff>
<normalon>:/core/icons/ic_nel_delete_item.png</normalon>:/core/icons/ic_nel_add_item.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QToolButton" name="addFilterButton_3">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../core/core.qrc">
<normaloff>:/core/icons/ic_nel_add_item.png</normaloff>
<normalon>:/core/icons/ic_nel_delete_item.png</normalon>:/core/icons/ic_nel_add_item.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Placement</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="margin">
<number>6</number>
</property>
<property name="spacing">
<number>3</number>
</property>
<item row="0" column="0">
<widget class="QComboBox" name="rotComboBox">
<item>
<property name="text">
<string>0°</string>
</property>
</item>
<item>
<property name="text">
<string>90°</string>
</property>
</item>
<item>
<property name="text">
<string>180°</string>
</property>
</item>
<item>
<property name="text">
<string>270°</string>
</property>
</item>
<item>
<property name="text">
<string>Random</string>
</property>
</item>
<item>
<property name="text">
<string>Full cycle</string>
</property>
</item>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="flipComboBox">
<item>
<property name="text">
<string>NoFlip</string>
</property>
</item>
<item>
<property name="text">
<string>Flip</string>
</property>
</item>
<item>
<property name="text">
<string>Random</string>
</property>
</item>
<item>
<property name="text">
<string>Fyll cycle</string>
</property>
</item>
</widget>
</item>
<item row="0" column="2">
<widget class="QCheckBox" name="forceCheckBox">
<property name="text">
<string>Force</string>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QCheckBox" name="propogateCheckBox">
<property name="text">
<string>Not propogate</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="0">
<widget class="QListView" name="listView">
<property name="alternatingRowColors">
<bool>false</bool>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="spacing">
<number>1</number>
</property>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="../core/core.qrc"/>
</resources>
<connections>
<connection>
<sender>addFilterButton_1</sender>
<signal>toggled(bool)</signal>
<receiver>categoryTypeComboBox_2</receiver>
<slot>setVisible(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>20</x>
<y>36</y>
</hint>
<hint type="destinationlabel">
<x>81</x>
<y>53</y>
</hint>
</hints>
</connection>
<connection>
<sender>addFilterButton_1</sender>
<signal>toggled(bool)</signal>
<receiver>categoryValueComboBox_2</receiver>
<slot>setVisible(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>24</x>
<y>32</y>
</hint>
<hint type="destinationlabel">
<x>181</x>
<y>50</y>
</hint>
</hints>
</connection>
<connection>
<sender>addFilterButton_1</sender>
<signal>toggled(bool)</signal>
<receiver>logicComboBox_2</receiver>
<slot>setVisible(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>20</x>
<y>31</y>
</hint>
<hint type="destinationlabel">
<x>301</x>
<y>55</y>
</hint>
</hints>
</connection>
<connection>
<sender>addFilterButton_2</sender>
<signal>toggled(bool)</signal>
<receiver>categoryTypeComboBox_3</receiver>
<slot>setVisible(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>27</x>
<y>62</y>
</hint>
<hint type="destinationlabel">
<x>57</x>
<y>75</y>
</hint>
</hints>
</connection>
<connection>
<sender>addFilterButton_2</sender>
<signal>toggled(bool)</signal>
<receiver>categoryValueComboBox_3</receiver>
<slot>setVisible(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>23</x>
<y>58</y>
</hint>
<hint type="destinationlabel">
<x>156</x>
<y>76</y>
</hint>
</hints>
</connection>
<connection>
<sender>addFilterButton_2</sender>
<signal>toggled(bool)</signal>
<receiver>logicComboBox_3</receiver>
<slot>setVisible(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>23</x>
<y>53</y>
</hint>
<hint type="destinationlabel">
<x>255</x>
<y>77</y>
</hint>
</hints>
</connection>
<connection>
<sender>addFilterButton_3</sender>
<signal>toggled(bool)</signal>
<receiver>categoryTypeComboBox_4</receiver>
<slot>setVisible(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>32</x>
<y>94</y>
</hint>
<hint type="destinationlabel">
<x>44</x>
<y>104</y>
</hint>
</hints>
</connection>
<connection>
<sender>addFilterButton_3</sender>
<signal>toggled(bool)</signal>
<receiver>categoryValueComboBox_4</receiver>
<slot>setVisible(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>32</x>
<y>94</y>
</hint>
<hint type="destinationlabel">
<x>207</x>
<y>103</y>
</hint>
</hints>
</connection>
<connection>
<sender>addFilterButton_3</sender>
<signal>toggled(bool)</signal>
<receiver>logicComboBox_4</receiver>
<slot>setVisible(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>21</x>
<y>81</y>
</hint>
<hint type="destinationlabel">
<x>278</x>
<y>104</y>
</hint>
</hints>
</connection>
<connection>
<sender>addFilterButton_2</sender>
<signal>toggled(bool)</signal>
<receiver>addFilterButton_3</receiver>
<slot>setVisible(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>15</x>
<y>59</y>
</hint>
<hint type="destinationlabel">
<x>16</x>
<y>80</y>
</hint>
</hints>
</connection>
<connection>
<sender>addFilterButton_1</sender>
<signal>toggled(bool)</signal>
<receiver>addFilterButton_2</receiver>
<slot>setVisible(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>13</x>
<y>35</y>
</hint>
<hint type="destinationlabel">
<x>17</x>
<y>60</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View file

@ -0,0 +1,152 @@
// 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 "pixmap_database.h"
// NeL includes
#include <nel/misc/debug.h>
#include <nel/ligo/zone_region.h>
// STL includes
#include <vector>
#include <string>
// Qt includes
#include <QtCore/QDir>
#include <QtGui/QPainter>
#include <QtGui/QMessageBox>
#include <QtGui/QApplication>
#include <QtGui/QProgressDialog>
namespace LandscapeEditor
{
PixmapDatabase::PixmapDatabase(int textureSize)
: m_textureSize(textureSize),
m_errorPixmap(0)
{
m_errorPixmap = new QPixmap(QSize(m_textureSize, m_textureSize));
QPainter painter(m_errorPixmap);
painter.setRenderHint(QPainter::Antialiasing, true);
painter.fillRect(m_errorPixmap->rect(), QBrush(QColor(Qt::black)));
painter.setFont(QFont("Helvetica [Cronyx]", 14));
painter.setPen(QPen(Qt::red, 2, Qt::SolidLine));
painter.drawText(m_errorPixmap->rect(), Qt::AlignCenter | Qt::TextWordWrap,
QObject::tr("Pixmap and LIGO files not found. Set the correct data path and reload landscape."));
painter.end();
}
PixmapDatabase::~PixmapDatabase()
{
delete m_errorPixmap;
reset();
}
bool PixmapDatabase::loadPixmaps(const QString &zonePath, NLLIGO::CZoneBank &zoneBank, bool displayProgress)
{
QProgressDialog *progressDialog;
std::vector<std::string> listNames;
zoneBank.getCategoryValues ("zone", listNames);
if (displayProgress)
{
progressDialog = new QProgressDialog("Loading ligo zones.", "Cancel", 0, listNames.size());
progressDialog->show();
}
for (uint i = 0; i < listNames.size(); ++i)
{
QApplication::processEvents();
if (displayProgress)
progressDialog->setValue(i);
NLLIGO::CZoneBankElement *zoneBankItem = zoneBank.getElementByZoneName (listNames[i]);
// Read the texture file
QString zonePixmapName(listNames[i].c_str());
uint8 sizeX = zoneBankItem->getSizeX();
uint8 sizeY = zoneBankItem->getSizeY();
QPixmap *pixmap = new QPixmap(zonePath + zonePixmapName + ".png");
if (pixmap->isNull())
{
// Generate filled pixmap
QPixmap *emptyPixmap = new QPixmap(QSize(sizeX * m_textureSize, sizeY * m_textureSize));
QPainter painter(emptyPixmap);
painter.setRenderHint(QPainter::Antialiasing, true);
painter.fillRect(emptyPixmap->rect(), QBrush(QColor(Qt::black)));
painter.setFont(QFont("Helvetica [Cronyx]", 18));
painter.setPen(QPen(Qt::red, 2, Qt::SolidLine));
painter.drawText(emptyPixmap->rect(), Qt::AlignCenter, QObject::tr("Pixmap not found"));
painter.end();
delete pixmap;
m_pixmapMap.insert(zonePixmapName, emptyPixmap);
}
// All pixmaps must be have same size
else if (pixmap->width() != sizeX * m_textureSize)
{
QPixmap *scaledPixmap = new QPixmap(pixmap->scaled(sizeX * m_textureSize, sizeY * m_textureSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
delete pixmap;
m_pixmapMap.insert(zonePixmapName, scaledPixmap);
}
else
m_pixmapMap.insert(zonePixmapName, pixmap);
}
QPixmap *pixmap = new QPixmap(zonePath + "_unused_.png");
QPixmap *scaledPixmap = new QPixmap(pixmap->scaled(m_textureSize, m_textureSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
delete pixmap;
m_pixmapMap.insert(QString(STRING_UNUSED), scaledPixmap);
if (displayProgress)
delete progressDialog;
return true;
}
void PixmapDatabase::reset()
{
QStringList listNames(m_pixmapMap.keys());
Q_FOREACH(QString name, listNames)
{
QPixmap *pixmap = m_pixmapMap.value(name);
delete pixmap;
}
m_pixmapMap.clear();
}
QStringList PixmapDatabase::listPixmaps() const
{
return m_pixmapMap.keys();
}
QPixmap *PixmapDatabase::pixmap(const QString &zoneName) const
{
QPixmap *result = m_errorPixmap;
if (!m_pixmapMap.contains(zoneName))
nlwarning("QPixmap %s not found", zoneName.toStdString().c_str());
else
result = m_pixmapMap.value(zoneName);
return result;
}
int PixmapDatabase::textureSize() const
{
return m_textureSize;
}
} /* namespace LandscapeEditor */

View file

@ -0,0 +1,69 @@
// 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 PIXMAP_DATABASE_H
#define PIXMAP_DATABASE_H
// Project includes
#include "landscape_editor_global.h"
// NeL includes
#include <nel/ligo/zone_bank.h>
// Qt includes
#include <QtCore/QString>
#include <QtCore/QMap>
#include <QtGui/QPixmap>
namespace LandscapeEditor
{
/**
@class PixmapDatabase
@brief PixmapDatabase contains the image database
@details
*/
class LANDSCAPE_EDITOR_EXPORT PixmapDatabase
{
public:
PixmapDatabase(int textureSize = 256);
~PixmapDatabase();
/// Load all images(png) from zonePath, list images gets from zoneBank
bool loadPixmaps(const QString &zonePath, NLLIGO::CZoneBank &zoneBank, bool displayProgress = false);
/// Unload all images
void reset();
/// Get list names all loaded pixmaps
QStringList listPixmaps() const;
/// Get original pixmap
/// @return QPixmap* if the image is in the database ; otherwise returns 0.
QPixmap *pixmap(const QString &zoneName) const;
int textureSize() const;
private:
int m_textureSize;
QPixmap *m_errorPixmap;
QMap<QString, QPixmap *> m_pixmapMap;
};
} /* namespace LandscapeEditor */
#endif // PIXMAP_DATABASE_H

View file

@ -0,0 +1,61 @@
// 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 "project_settings_dialog.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 <QtCore/QSettings>
#include <QtGui/QFileDialog>
#include <QtGui/QFileDialog>
namespace LandscapeEditor
{
ProjectSettingsDialog::ProjectSettingsDialog(const QString &dataPath, QWidget *parent)
: QDialog(parent)
{
m_ui.setupUi(this);
m_ui.pathLineEdit->setText(dataPath);
setFixedHeight(sizeHint().height());
connect(m_ui.selectPathButton, SIGNAL(clicked()), this, SLOT(selectPath()));
}
ProjectSettingsDialog::~ProjectSettingsDialog()
{
}
QString ProjectSettingsDialog::dataPath() const
{
return m_ui.pathLineEdit->text();
}
void ProjectSettingsDialog::selectPath()
{
QString dataPath = QFileDialog::getExistingDirectory(this, tr("Select data path"), m_ui.pathLineEdit->text());
if (!dataPath.isEmpty())
m_ui.pathLineEdit->setText(dataPath);
}
} /* namespace LandscapeEditor */

View file

@ -0,0 +1,50 @@
// 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 PROJECT_SETTINGS_DIALOG_H
#define PROJECT_SETTINGS_DIALOG_H
// Project includes
#include "ui_project_settings_dialog.h"
#include "landscape_editor_global.h"
// Qt includes
namespace LandscapeEditor
{
class LANDSCAPE_EDITOR_EXPORT ProjectSettingsDialog: public QDialog
{
Q_OBJECT
public:
ProjectSettingsDialog(const QString &dataPath, QWidget *parent = 0);
~ProjectSettingsDialog();
QString dataPath() const;
private Q_SLOTS:
void selectPath();
private:
Ui::ProjectSettingsDialog m_ui;
}; /* class ProjectSettingsDialog */
} /* namespace LandscapeEditor */
#endif // PROJECT_SETTINGS_DIALOG_H

View file

@ -0,0 +1,103 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ProjectSettingsDialog</class>
<widget class="QDialog" name="ProjectSettingsDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>419</width>
<height>93</height>
</rect>
</property>
<property name="windowTitle">
<string>Project settings</string>
</property>
<property name="windowIcon">
<iconset resource="landscape_editor.qrc">
<normaloff>:/icons/ic_nel_landscape_settings.png</normaloff>:/icons/ic_nel_landscape_settings.png</iconset>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Data directory:</string>
</property>
<property name="buddy">
<cstring>pathLineEdit</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="pathLineEdit"/>
</item>
<item row="0" column="2">
<widget class="QToolButton" name="selectPathButton">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Context:</string>
</property>
<property name="buddy">
<cstring>contextComboBox</cstring>
</property>
</widget>
</item>
<item row="1" column="1" colspan="2">
<widget class="QComboBox" name="contextComboBox"/>
</item>
<item row="2" column="0" colspan="3">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="landscape_editor.qrc"/>
</resources>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>ProjectSettingsDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>257</x>
<y>83</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>ProjectSettingsDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>325</x>
<y>83</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View file

@ -0,0 +1,228 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SnapshotDialog</class>
<widget class="QDialog" name="SnapshotDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>230</width>
<height>187</height>
</rect>
</property>
<property name="windowTitle">
<string>Snapshot</string>
</property>
<property name="windowIcon">
<iconset resource="landscape_editor.qrc">
<normaloff>:/icons/ic_snapshot.png</normaloff>:/icons/ic_snapshot.png</iconset>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QRadioButton" name="originalSizeRadioButton">
<property name="text">
<string>Original size</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="resSpinBox">
<property name="maximum">
<number>1024</number>
</property>
<property name="value">
<number>128</number>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QRadioButton" name="customSizeRadioButton">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Custom size</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QGroupBox" name="groupBox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="title">
<string/>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="1">
<widget class="QSpinBox" name="widthSpinBox">
<property name="maximum">
<number>99999</number>
</property>
<property name="value">
<number>512</number>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Height:</string>
</property>
<property name="buddy">
<cstring>heightSpinBox</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="heightSpinBox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="maximum">
<number>99999</number>
</property>
<property name="value">
<number>512</number>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Width:</string>
</property>
<property name="buddy">
<cstring>widthSpinBox</cstring>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QCheckBox" name="keepRatioCheckBox">
<property name="text">
<string>Keep bitmap ratio</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="3" column="0">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<tabstops>
<tabstop>originalSizeRadioButton</tabstop>
<tabstop>customSizeRadioButton</tabstop>
<tabstop>widthSpinBox</tabstop>
<tabstop>heightSpinBox</tabstop>
<tabstop>keepRatioCheckBox</tabstop>
<tabstop>buttonBox</tabstop>
</tabstops>
<resources>
<include location="landscape_editor.qrc"/>
</resources>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>SnapshotDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>227</x>
<y>164</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>158</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>SnapshotDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>276</x>
<y>170</y>
</hint>
<hint type="destinationlabel">
<x>285</x>
<y>158</y>
</hint>
</hints>
</connection>
<connection>
<sender>customSizeRadioButton</sender>
<signal>toggled(bool)</signal>
<receiver>groupBox</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>59</x>
<y>39</y>
</hint>
<hint type="destinationlabel">
<x>78</x>
<y>62</y>
</hint>
</hints>
</connection>
<connection>
<sender>keepRatioCheckBox</sender>
<signal>toggled(bool)</signal>
<receiver>heightSpinBox</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>84</x>
<y>122</y>
</hint>
<hint type="destinationlabel">
<x>178</x>
<y>106</y>
</hint>
</hints>
</connection>
<connection>
<sender>keepRatioCheckBox</sender>
<signal>toggled(bool)</signal>
<receiver>label_2</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>55</x>
<y>129</y>
</hint>
<hint type="destinationlabel">
<x>48</x>
<y>103</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View file

@ -0,0 +1,71 @@
// 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 "snapshot_dialog.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 <QtCore/QSettings>
#include <QtGui/QFileDialog>
namespace LandscapeEditor
{
SnapshotDialog::SnapshotDialog(QWidget *parent)
: QDialog(parent)
{
m_ui.setupUi(this);
setFixedHeight(sizeHint().height());
}
SnapshotDialog::~SnapshotDialog()
{
}
bool SnapshotDialog::isCustomSize() const
{
return m_ui.customSizeRadioButton->isChecked();
}
bool SnapshotDialog::isKeepRatio() const
{
return m_ui.keepRatioCheckBox->isChecked();
}
int SnapshotDialog::resolutionZone() const
{
return m_ui.resSpinBox->value();
}
int SnapshotDialog::widthSnapshot() const
{
return m_ui.widthSpinBox->value();
}
int SnapshotDialog::heightSnapshot() const
{
return m_ui.heightSpinBox->value();
}
} /* namespace LandscapeEditor */

View file

@ -0,0 +1,53 @@
// 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 SNAPSHOT_DIALOG_H
#define SNAPSHOT_DIALOG_H
// Project includes
#include "ui_shapshot_dialog.h"
// Qt includes
namespace LandscapeEditor
{
class SnapshotDialog: public QDialog
{
Q_OBJECT
public:
SnapshotDialog(QWidget *parent = 0);
~SnapshotDialog();
bool isCustomSize() const;
bool isKeepRatio() const;
int resolutionZone() const;
int widthSnapshot() const;
int heightSnapshot() const;
private Q_SLOTS:
private:
Ui::SnapshotDialog m_ui;
}; /* class SnapshotDialog */
} /* namespace LandscapeEditor */
#endif // SNAPSHOT_DIALOG_H

View file

@ -0,0 +1,193 @@
// 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 "zone_region_editor.h"
// NeL includes
#include <nel/misc/debug.h>
#include <nel/misc/file.h>
#include <nel/misc/i_xml.h>
#include <nel/misc/o_xml.h>
// Qt includes
#include <QtGui/QMessageBox>
namespace LandscapeEditor
{
ZoneRegionObject::ZoneRegionObject()
{
m_fileName = "";
}
ZoneRegionObject::~ZoneRegionObject()
{
}
bool ZoneRegionObject::load(const std::string &fileName)
{
bool result = true;
try
{
// Open it
NLMISC::CIFile fileIn;
if (fileIn.open(fileName))
{
NLMISC::CIXml xml(true);
xml.init(fileIn);
m_zoneRegion.serial(xml);
}
else
{
nlwarning("Can't open file %s for reading", fileName.c_str());
result = false;
}
}
catch (NLMISC::Exception &e)
{
nlwarning("Error reading file %s : %s", fileName.c_str(), e.what ());
result = false;
}
if (result)
m_fileName = fileName;
return result;
}
bool ZoneRegionObject::save()
{
if (m_fileName.empty())
return false;
bool result = true;
// Save the landscape
try
{
// Open file for writing
NLMISC::COFile fileOut;
if (fileOut.open(m_fileName, false, false, true))
{
// Be careful with the flushing of the COXml object
{
NLMISC::COXml xmlOut;
xmlOut.init(&fileOut);
m_zoneRegion.serial(xmlOut);
// Done
m_modified = false;
}
fileOut.close();
}
else
{
nlwarning("Can't open file %s for writing.", m_fileName.c_str());
result = false;
}
}
catch (NLMISC::Exception &e)
{
nlwarning("Error writing file %s : %s", m_fileName.c_str(), e.what());
result = false;
}
return result;
}
std::string ZoneRegionObject::fileName() const
{
return m_fileName;
}
void ZoneRegionObject::setFileName(const std::string &fileName)
{
m_fileName = fileName;
}
void ZoneRegionObject::ligoData(LigoData &data, const sint32 x, const sint32 y)
{
/*
nlassert((x >= m_zoneRegion.getMinX()) &&
(x <= m_zoneRegion.getMaxX()) &&
(y >= m_zoneRegion.getMinY()) &&
(y <= m_zoneRegion.getMaxY()));
*/
data.posX = m_zoneRegion.getPosX(x, y);
data.posY = m_zoneRegion.getPosY(x, y);
data.zoneName = m_zoneRegion.getName(x, y);
data.rot = m_zoneRegion.getRot(x, y);
data.flip = m_zoneRegion.getFlip(x, y);
data.sharingMatNames[0] = m_zoneRegion.getSharingMatNames(x, y, 0);
data.sharingMatNames[1] = m_zoneRegion.getSharingMatNames(x, y, 1);
data.sharingMatNames[2] = m_zoneRegion.getSharingMatNames(x, y, 2);
data.sharingMatNames[3] = m_zoneRegion.getSharingMatNames(x, y, 3);
data.sharingCutEdges[0] = m_zoneRegion.getSharingCutEdges(x, y, 0);
data.sharingCutEdges[1] = m_zoneRegion.getSharingCutEdges(x, y, 1);
data.sharingCutEdges[2] = m_zoneRegion.getSharingCutEdges(x, y, 2);
data.sharingCutEdges[3] = m_zoneRegion.getSharingCutEdges(x, y, 3);
}
void ZoneRegionObject::setLigoData(const LigoData &data, const sint32 x, const sint32 y)
{
/*
nlassert((x >= m_zoneRegion.getMinX()) &&
(x <= m_zoneRegion.getMaxX()) &&
(y >= m_zoneRegion.getMinY()) &&
(y <= m_zoneRegion.getMaxY()));
*/
m_zoneRegion.setPosX(x, y, data.posX);
m_zoneRegion.setPosY(x, y, data.posY);
m_zoneRegion.setName(x, y, data.zoneName);
m_zoneRegion.setRot(x, y, data.rot);
m_zoneRegion.setFlip(x, y, data.flip);
m_zoneRegion.setSharingMatNames(x, y, 0, data.sharingMatNames[0]);
m_zoneRegion.setSharingMatNames(x, y, 1, data.sharingMatNames[1]);
m_zoneRegion.setSharingMatNames(x, y, 2, data.sharingMatNames[2]);
m_zoneRegion.setSharingMatNames(x, y, 3, data.sharingMatNames[3]);
m_zoneRegion.setSharingCutEdges(x, y, 0, data.sharingCutEdges[0]);
m_zoneRegion.setSharingCutEdges(x, y, 1, data.sharingCutEdges[1]);
m_zoneRegion.setSharingCutEdges(x, y, 2, data.sharingCutEdges[2]);
m_zoneRegion.setSharingCutEdges(x, y, 3, data.sharingCutEdges[3]);
}
NLLIGO::CZoneRegion &ZoneRegionObject::ligoZoneRegion()
{
return m_zoneRegion;
}
void ZoneRegionObject::setLigoZoneRegion(const NLLIGO::CZoneRegion &zoneRegion)
{
m_zoneRegion = zoneRegion;
}
bool ZoneRegionObject::checkPos(const sint32 x, const sint32 y)
{
return ((x >= m_zoneRegion.getMinX()) &&
(x <= m_zoneRegion.getMaxX()) &&
(y >= m_zoneRegion.getMinY()) &&
(y <= m_zoneRegion.getMaxY()));
}
bool ZoneRegionObject::isModified() const
{
return m_modified;
}
void ZoneRegionObject::setModified(bool modified)
{
m_modified = modified;
}
} /* namespace LandscapeEditor */

View file

@ -0,0 +1,135 @@
// 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_EDITOR_H
#define LANDSCAPE_EDITOR_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>
// Qt includes
namespace LandscapeEditor
{
// Data
struct LigoData
{
uint8 posX;
uint8 posY;
uint8 rot;
uint8 flip;
std::string zoneName;
std::string sharingMatNames[4];
uint8 sharingCutEdges[4];
LigoData()
{
posX = 0;
posY = 0;
zoneName = "";
rot = 0;
flip = 0;
sharingMatNames[0] = "";
sharingMatNames[1] = "";
sharingMatNames[2] = "";
sharingMatNames[3] = "";
sharingCutEdges[0] = 0;
sharingCutEdges[1] = 0;
sharingCutEdges[2] = 0;
sharingCutEdges[3] = 0;
}
bool operator!= (const LigoData &other) const
{
return (posX != other.posX) ||
(posY != other.posY) ||
(rot != other.rot) ||
(flip != other.flip) ||
(zoneName != other.zoneName) ||
(sharingMatNames[0] != other.sharingMatNames[0]) ||
(sharingMatNames[1] != other.sharingMatNames[1]) ||
(sharingMatNames[2] != other.sharingMatNames[2]) ||
(sharingMatNames[3] != other.sharingMatNames[3]) ||
(sharingCutEdges[0] != other.sharingCutEdges[0]) ||
(sharingCutEdges[1] != other.sharingCutEdges[1]) ||
(sharingCutEdges[2] != other.sharingCutEdges[2]) ||
(sharingCutEdges[3] != other.sharingCutEdges[3]);
}
};
/**
@class ZoneRegionObject
@brief
@details
*/
class LANDSCAPE_EDITOR_EXPORT ZoneRegionObject
{
public:
ZoneRegionObject();
~ZoneRegionObject();
/// Load landscape data from file
bool load(const std::string &fileName);
/// Save landscape data to file (before save, should set file name).
bool save();
/// Get ligo data
void ligoData(LigoData &data, const sint32 x, const sint32 y);
/// Set ligo data
void setLigoData(const LigoData &data, const sint32 x, const sint32 y);
/// Get file name
std::string fileName() const;
/// Set file name, use for saving data in file
void setFileName(const std::string &fileName);
/// Accessor to LIGO CZoneRegion
NLLIGO::CZoneRegion &ligoZoneRegion();
void setLigoZoneRegion(const NLLIGO::CZoneRegion &zoneRegion);
/// Check position, it belongs to the landscape
bool checkPos(const sint32 x, const sint32 y);
/// Helper flag to know if a ps has been modified
/// @{
bool isModified() const;
void setModified(bool modified);
/// @}
private:
bool m_modified;
bool m_editable;
std::string m_fileName;
NLLIGO::CZoneRegion m_zoneRegion;
};
} /* namespace LandscapeEditor */
#endif // LANDSCAPE_EDITOR_H

View file

@ -0,0 +1,51 @@
INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}
${LIBXML2_INCLUDE_DIR}
${QT_INCLUDES})
FILE(GLOB SRC *.cpp *.h)
SET(OVQT_EXT_SYS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/../../extension_system/iplugin.h
${CMAKE_CURRENT_SOURCE_DIR}/../../extension_system/iplugin_manager.h
${CMAKE_CURRENT_SOURCE_DIR}/../../extension_system/iplugin_spec.h)
SET(OVQT_PLUGIN_WORLD_EDITOR_HDR world_editor_plugin.h
world_editor_window.h
world_editor_scene.h
primitives_model.h
primitives_view.h
)
SET(OVQT_PLUGIN_WORLD_EDITOR_UIS world_editor_window.ui
)
SET(OVQT_PLUGIN_WORLD_EDITOR_RCS world_editor.qrc)
SET(QT_USE_QTGUI TRUE)
SET(QT_USE_QTOPENGL TRUE)
QT4_ADD_RESOURCES(OVQT_PLUGIN_WORLD_EDITOR_RC_SRCS ${OVQT_PLUGIN_WORLD_EDITOR_RCS})
QT4_WRAP_CPP(OVQT_PLUGIN_WORLD_EDITOR_MOC_SRC ${OVQT_PLUGIN_WORLD_EDITOR_HDR})
QT4_WRAP_UI(OVQT_PLUGIN_WORLD_EDITOR_UI_HDRS ${OVQT_PLUGIN_WORLD_EDITOR_UIS})
SOURCE_GROUP(QtResources FILES ${OVQT_PLUGIN_WORLD_EDITOR_UIS})
SOURCE_GROUP(QtGeneratedUiHdr FILES ${OVQT_PLUGIN_WORLD_EDITOR_UI_HDRS})
SOURCE_GROUP(QtGeneratedMocQrcSrc FILES ${OVQT_PLUGIN_WORLD_EDITOR_MOC_SRC} OVQT_PLUGIN_WORLD_EDITOR_RC_SRCS)
SOURCE_GROUP("World Editor Plugin" FILES ${SRC})
SOURCE_GROUP("OVQT Extension System" FILES ${OVQT_EXT_SYS_SRC})
ADD_LIBRARY(ovqt_plugin_world_editor MODULE ${SRC}
${OVQT_PLUGIN_WORLD_EDITOR_MOC_SRC}
${OVQT_EXT_SYS_SRC}
${OVQT_PLUGIN_WORLD_EDITOR_UI_HDRS}
${OVQT_PLUGIN_WORLD_EDITOR_RC_SRCS})
TARGET_LINK_LIBRARIES(ovqt_plugin_world_editor ovqt_plugin_core ovqt_plugin_landscape_editor nelmisc nel3d ${QT_LIBRARIES} ${QT_QTOPENGL_LIBRARY})
NL_DEFAULT_PROPS(ovqt_plugin_world_editor "NeL, Tools, 3D: Object Viewer Qt Plugin: World Editor")
NL_ADD_RUNTIME_FLAGS(ovqt_plugin_world_editor)
NL_ADD_LIB_SUFFIX(ovqt_plugin_world_editor)
ADD_DEFINITIONS(-DWORLD_EDITOR_LIBRARY ${LIBXML2_DEFINITIONS} -DQT_PLUGIN -DQT_SHARED ${QT_DEFINITIONS})
INSTALL(TARGETS ovqt_plugin_world_editor LIBRARY DESTINATION lib RUNTIME DESTINATION bin ARCHIVE DESTINATION lib COMPONENT tools3d)

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

View file

@ -0,0 +1,257 @@
// 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 "primitive_item.h"
#include "world_editor_misc.h"
#include "world_editor_constants.h"
#include "../landscape_editor/landscape_editor_constants.h"
// NeL includes
#include <nel/ligo/ligo_config.h>
// Qt includes
#include <QtCore/QStringList>
#include <QtCore/QFile>
namespace WorldEditor
{
Node::Node()
: m_parent(0)
{
}
Node::~Node()
{
if (m_parent)
m_parent->removeChildNode(this);
qDeleteAll(m_children);
nlassert(m_children.isEmpty());
m_data.clear();
}
void Node::prependChildNode(Node *node)
{
// Node is already a child
nlassert(!m_children.contains(node));
// Node already has a parent
nlassert(!m_children.contains(node));
m_children.prepend(node);
node->m_parent = this;
}
void Node::appendChildNode(Node *node)
{
// Node is already a child
nlassert(!m_children.contains(node));
// Node already has a parent
nlassert(!m_children.contains(node));
m_children.append(node);
node->m_parent = this;
}
void Node::insertChildNodeBefore(Node *node, Node *before)
{
// Node is already a child
nlassert(!m_children.contains(node));
// Node already has a parent
nlassert(!m_children.contains(node));
int idx = before ? m_children.indexOf(before) : -1;
if (idx == -1)
m_children.append(node);
else
m_children.insert(idx, node);
node->m_parent = this;
}
void Node::insertChildNodeAfter(Node *node, Node *after)
{
// Node is already a child
nlassert(!m_children.contains(node));
// Node already has a parent
nlassert(!m_children.contains(node));
int idx = after ? m_children.indexOf(after) : -1;
if (idx == -1)
m_children.append(node);
else
m_children.insert(idx + 1, node);
node->m_parent = this;
}
void Node::removeChildNode(Node *node)
{
nlassert(m_children.contains(node));
nlassert(node->parent() == this);
m_children.removeOne(node);
node->m_parent = 0;
}
Node *Node::child(int row)
{
return m_children.at(row);
}
int Node::childCount() const
{
return m_children.count();
}
QVariant Node::data(int key) const
{
return m_data[key];
}
void Node::setData(int key, const QVariant &data)
{
m_data[key] = data;
}
Node *Node::parent()
{
return m_parent;
}
int Node::row() const
{
if (m_parent)
return m_parent->m_children.indexOf(const_cast<Node *>(this));
return 0;
}
Node::NodeType Node::type() const
{
return BasicNodeType;
}
WorldEditNode::WorldEditNode(const QString &name)
{
setData(Qt::DisplayRole, name);
setData(Qt::DecorationRole, QIcon(Constants::ICON_WORLD_EDITOR));
}
WorldEditNode::~WorldEditNode()
{
}
Node::NodeType WorldEditNode::type() const
{
return WorldEditNodeType;
}
LandscapeNode::LandscapeNode(const QString &name)
{
setData(Qt::DisplayRole, name);
setData(Qt::DecorationRole, QIcon(LandscapeEditor::Constants::ICON_ZONE_ITEM));
}
LandscapeNode::~LandscapeNode()
{
}
Node::NodeType LandscapeNode::type() const
{
return LandscapeNodeType;
}
PrimitiveNode::PrimitiveNode(NLLIGO::IPrimitive *primitive)
: m_primitive(primitive)
{
setData(Qt::DisplayRole, QString(m_primitive->getName().c_str()));
setData(Qt::ToolTipRole, QString(m_primitive->getClassName().c_str()));
std::string className;
m_primitive->getPropertyByName("class", className);
// Set Icon
QString nameIcon = QString("./old_ico/%1.ico").arg(className.c_str());
QIcon icon(nameIcon);
if (!QFile::exists(nameIcon))
{
if (primitive->getParent() == NULL)
icon = QIcon("./old_ico/root.ico");
else if (primitive->getNumChildren() == 0)
icon = QIcon("./old_ico/property.ico");
else
icon = QIcon("./old_ico/folder_h.ico");
}
setData(Qt::DecorationRole, icon);
//setData(3, QString(className.c_str()));
}
PrimitiveNode::~PrimitiveNode()
{
}
NLLIGO::IPrimitive *PrimitiveNode::primitive() const
{
return m_primitive;
}
const NLLIGO::CPrimitiveClass *PrimitiveNode::primitiveClass() const
{
return NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig->getPrimitiveClass(*m_primitive);
}
RootPrimitiveNode *PrimitiveNode::rootPrimitiveNode()
{
Node *node = this;
while (node && (node->type() != Node::RootPrimitiveNodeType))
node = node->parent();
return (RootPrimitiveNode *)node;
}
Node::NodeType PrimitiveNode::type() const
{
return PrimitiveNodeType;
}
RootPrimitiveNode::RootPrimitiveNode(const QString &name, NLLIGO::CPrimitives *primitives)
: PrimitiveNode(primitives->RootNode),
m_primitives(primitives)
{
setData(Qt::DisplayRole, name);
}
RootPrimitiveNode::~RootPrimitiveNode()
{
}
NLLIGO::CPrimitives *RootPrimitiveNode::primitives() const
{
return m_primitives;
}
Node::NodeType RootPrimitiveNode::type() const
{
return RootPrimitiveNodeType;
}
} /* namespace WorldEditor */

View file

@ -0,0 +1,179 @@
// 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 PRIMITIVE_ITEM_H
#define PRIMITIVE_ITEM_H
// Project includes
// NeL includes
#include <nel/ligo/primitive.h>
#include <nel/ligo/primitive_class.h>
// Qt includes
#include <QList>
#include <QIcon>
#include <QVariant>
namespace WorldEditor
{
class WorldEditNode;
class RootPrimitiveNode;
class LandscapeNode;
class PrimitiveNode;
/*
@class Node
@brief
@details
*/
class Node
{
public:
enum NodeType
{
BasicNodeType,
WorldEditNodeType,
RootPrimitiveNodeType,
LandscapeNodeType,
PrimitiveNodeType,
UserNodeType = 1024
};
Node();
virtual ~Node();
/// Remove child node from the child list.
void removeChildNode(Node *node);
/// Insert node at the beginning of the list.
void prependChildNode(Node *node);
/// Insert node at the end of the list.
void appendChildNode(Node *node);
/// Insert node in front of the node pointed to by the pointer before.
void insertChildNodeBefore(Node *node, Node *before);
/// Insert node in back of the node pointed to by the pointer after.
void insertChildNodeAfter(Node *node, Node *after);
/// Return the node at index position row in the child list.
Node *child(int row);
/// Return the number of nodes in the list.
int childCount() const;
/// Return a row index this node.
int row() const;
/// Return a pointer to this node's parent item. If this node does not have a parent, 0 is returned.
Node *parent();
/// Set this node's custom data for the key key to value.
void setData(int key, const QVariant &data);
/// Return this node's custom data for the key key as a QVariant.
QVariant data(int key) const;
/// Return a type this node.
virtual NodeType type() const;
private:
Q_DISABLE_COPY(Node)
Node *m_parent;
QList<Node *> m_children;
QHash<int, QVariant> m_data;
};
/*
@class WorldEditNode
@brief
@details
*/
class WorldEditNode: public Node
{
public:
WorldEditNode(const QString &name);
virtual ~WorldEditNode();
virtual NodeType type() const;
private:
};
/*
@class LandscapeNode
@brief
@details
*/
class LandscapeNode: public Node
{
public:
LandscapeNode(const QString &name);
virtual ~LandscapeNode();
virtual NodeType type() const;
private:
};
/*
@class PrimitiveNode
@brief
@details
*/
class PrimitiveNode: public Node
{
public:
PrimitiveNode(NLLIGO::IPrimitive *primitive);
virtual ~PrimitiveNode();
NLLIGO::IPrimitive *primitive() const;
const NLLIGO::CPrimitiveClass *primitiveClass() const;
RootPrimitiveNode *rootPrimitiveNode();
virtual NodeType type() const;
private:
NLLIGO::IPrimitive *m_primitive;
};
/*
@class RootPrimitiveNode
@brief
@details
*/
class RootPrimitiveNode: public PrimitiveNode
{
public:
RootPrimitiveNode(const QString &name, NLLIGO::CPrimitives *primitives);
virtual ~RootPrimitiveNode();
NLLIGO::CPrimitives *primitives() const;
virtual NodeType type() const;
private:
NLLIGO::CPrimitives *m_primitives;
};
} /* namespace WorldEditor */
#endif // PRIMITIVE_ITEM_H

View file

@ -0,0 +1,278 @@
// 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 "primitive_item.h"
#include "primitives_model.h"
#include "world_editor_misc.h"
// NeL includes
#include <nel/misc/debug.h>
#include <nel/ligo/primitive.h>
#include <nel/ligo/primitive_utils.h>
// Qt includes
#include <QtGui>
namespace WorldEditor
{
PrimitivesTreeModel::PrimitivesTreeModel(QObject *parent)
: QAbstractItemModel(parent),
m_worldEditNode(0)
{
m_rootNode = new Node();
m_rootNode->setData(Qt::DisplayRole, "Name");
}
PrimitivesTreeModel::~PrimitivesTreeModel()
{
delete m_rootNode;
}
int PrimitivesTreeModel::columnCount(const QModelIndex &parent) const
{
/* if (parent.isValid())
return static_cast<BaseTreeItem *>(parent.internalPointer())->columnCount();
else
return m_rootItem->columnCount();
*/
return 1;
}
QVariant PrimitivesTreeModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
Node *item = static_cast<Node *>(index.internalPointer());
switch (role)
{
// case Qt::TextAlignmentRole:
// return int(Qt::AlignLeft | Qt::AlignVCenter);
case Qt::DisplayRole:
return item->data(Qt::DisplayRole);
case Qt::DecorationRole:
return item->data(Qt::DecorationRole);
default:
return QVariant();
}
}
Qt::ItemFlags PrimitivesTreeModel::flags(const QModelIndex &index) const
{
if (!index.isValid())
return 0;
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}
QVariant PrimitivesTreeModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
// return m_rootNode->data(section);
return m_rootNode->data(Qt::DisplayRole);
return QVariant();
}
QModelIndex PrimitivesTreeModel::index(int row, int column, const QModelIndex &parent) const
{
if (!hasIndex(row, column, parent))
return QModelIndex();
Node *parentNode;
if (!parent.isValid())
parentNode = m_rootNode;
else
parentNode = static_cast<Node *>(parent.internalPointer());
Node *childNode = parentNode->child(row);
if (childNode)
return createIndex(row, column, childNode);
else
return QModelIndex();
}
QModelIndex PrimitivesTreeModel::parent(const QModelIndex &index) const
{
if (!index.isValid())
return QModelIndex();
Node *childNode = static_cast<Node *>(index.internalPointer());
Node *parentNode = childNode->parent();
if (parentNode == m_rootNode)
return QModelIndex();
return createIndex(parentNode->row(), 0, parentNode);
}
int PrimitivesTreeModel::rowCount(const QModelIndex &parent) const
{
Node *parentNode;
if (parent.column() > 0)
return 0;
if (!parent.isValid())
parentNode = m_rootNode;
else
parentNode = static_cast<Node *>(parent.internalPointer());
return parentNode->childCount();
}
Path PrimitivesTreeModel::pathFromIndex(const QModelIndex &index)
{
QModelIndex iter = index;
Path path;
while(iter.isValid())
{
path.prepend(PathItem(iter.row(), iter.column()));
iter = iter.parent();
}
return path;
}
QModelIndex PrimitivesTreeModel::pathToIndex(const Path &path)
{
QModelIndex iter;
for(int i = 0; i < path.size(); i++)
{
iter = index(path[i].first, path[i].second, iter);
}
return iter;
}
void PrimitivesTreeModel::createWorldEditNode(const QString &fileName)
{
beginResetModel();
m_worldEditNode = new WorldEditNode(fileName);
m_rootNode->appendChildNode(m_worldEditNode);
endResetModel();
}
void PrimitivesTreeModel::deleteWorldEditNode()
{
beginResetModel();
if (m_worldEditNode != 0)
{
delete m_worldEditNode;
m_worldEditNode = 0;
}
endResetModel();
}
Path PrimitivesTreeModel::createLandscapeNode(const QString &fileName)
{
if (m_worldEditNode == 0)
createWorldEditNode("NewWorldEdit");
QModelIndex parentIndex = index(0, 0, QModelIndex());
beginInsertRows(parentIndex, 0, 0);
LandscapeNode *newNode = new LandscapeNode(fileName);
m_worldEditNode->prependChildNode(newNode);
endInsertRows();
return pathFromIndex(index(0, 0, index(0, 0, QModelIndex())));
}
Path PrimitivesTreeModel::createRootPrimitiveNode(const QString &fileName, NLLIGO::CPrimitives *primitives)
{
if (m_worldEditNode == 0)
createWorldEditNode("NewWorldEdit");
// Get position
int pos = m_worldEditNode->childCount();
QModelIndex parentIndex = index(0, 0, QModelIndex());
// Add root node in tree model
beginInsertRows(parentIndex, pos, pos);
RootPrimitiveNode *newNode = new RootPrimitiveNode(fileName, primitives);
m_worldEditNode->appendChildNode(newNode);
endInsertRows();
QModelIndex rootPrimIndex = index(pos, 0, parentIndex);
// Scan childs items and add in the tree model
for (uint i = 0; i < primitives->RootNode->getNumChildren(); ++i)
{
NLLIGO::IPrimitive *childPrim;
primitives->RootNode->getChild(childPrim, i);
createChildNodes(childPrim, rootPrimIndex);
}
return pathFromIndex(rootPrimIndex);
}
Path PrimitivesTreeModel::createPrimitiveNode(NLLIGO::IPrimitive *primitive, const Path &parent)
{
QModelIndex parentIndex = pathToIndex(parent);
Node *parentNode = static_cast<Node *>(parentIndex.internalPointer());
int pos = parentNode->childCount();
createChildNodes(primitive, parentIndex);
return pathFromIndex(index(pos, 0, parentIndex));
}
void PrimitivesTreeModel::deleteNode(const Path &path)
{
QModelIndex nodeIndex = pathToIndex(path);
QModelIndex parentIndex = nodeIndex.parent();
Node *node = static_cast<Node *>(nodeIndex.internalPointer());
// Scan childs items and delete from the tree model
removeChildNodes(node, parentIndex);
}
void PrimitivesTreeModel::createChildNodes(NLLIGO::IPrimitive *primitive, const QModelIndex &parent)
{
Node *parentNode = static_cast<Node *>(parent.internalPointer());
int pos = parentNode->childCount();
// Add node in the tree model
beginInsertRows(parent, pos, pos);
PrimitiveNode *newNode = new PrimitiveNode(primitive);
parentNode->appendChildNode(newNode);
endInsertRows();
// Scan childs items and add in the tree model
QModelIndex childIndex = index(pos, 0, parent);
for (uint i = 0; i < primitive->getNumChildren(); ++i)
{
NLLIGO::IPrimitive *childPrim;
primitive->getChild(childPrim, i);
createChildNodes(childPrim, childIndex);
}
}
void PrimitivesTreeModel::removeChildNodes(Node *node, const QModelIndex &parent)
{
// Delete all child nodes from the tree model
while (node->childCount() != 0)
removeChildNodes(node->child(node->childCount() - 1), parent.child(node->row(), 0));
// Delete node from the tree model
beginRemoveRows(parent, node->row(), node->row());
delete node;
endRemoveRows();
}
} /* namespace WorldEditor */

View file

@ -0,0 +1,99 @@
// 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 PRIMITIVES_MODEL_H
#define PRIMITIVES_MODEL_H
// NeL includes
#include <nel/misc/vector.h>
#include <nel/ligo/primitive.h>
#include <nel/ligo/primitive_class.h>
#include <nel/ligo/ligo_config.h>
// Qt includes
#include <QAbstractItemModel>
#include <QModelIndex>
#include <QVariant>
namespace WorldEditor
{
class Node;
class WorldEditNode;
typedef QPair<int, int> PathItem;
/*
@typedef Path
@brief It store a list of row and column numbers which have to walk through from the root index of the model to reach the need item
*/
typedef QList<PathItem> Path;
/**
@class PrimitivesTreeModel
@brief
@details
*/
class PrimitivesTreeModel : public QAbstractItemModel
{
Q_OBJECT
public:
PrimitivesTreeModel(QObject *parent = 0);
~PrimitivesTreeModel();
QVariant data(const QModelIndex &index, int role) const;
Qt::ItemFlags flags(const QModelIndex &index) const;
QVariant headerData(int section, Qt::Orientation orientation,
int role = Qt::DisplayRole) const;
QModelIndex index(int row, int column,
const QModelIndex &parent = QModelIndex()) const;
QModelIndex parent(const QModelIndex &index) const;
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent = QModelIndex()) const;
/// Convert QModelIndex to the persistent index - @Path.
/// @Path is a list of [row,column] pairs showing us the way through the model.
Path pathFromIndex(const QModelIndex &index);
QModelIndex pathToIndex(const Path &path);
void createWorldEditNode(const QString &fileName);
void deleteWorldEditNode();
/// Add new landscape node in tree model.
Path createLandscapeNode(const QString &fileName);
/// Add new root primitive node and all sub-primitives in the tree model.
Path createRootPrimitiveNode(const QString &fileName, NLLIGO::CPrimitives *primitives);
/// Add new primitive node and all sub-primitives in the tree model.
Path createPrimitiveNode(NLLIGO::IPrimitive *primitive, const Path &parent);
/// Delete node and all child nodes from the tree model
void deleteNode(const Path &path);
private:
void createChildNodes(NLLIGO::IPrimitive *primitive, const QModelIndex &parent);
void removeChildNodes(Node *node, const QModelIndex &parent);
Node *m_rootNode;
WorldEditNode *m_worldEditNode;
};
} /* namespace WorldEditor */
#endif // PRIMITIVES_MODEL_H

View file

@ -0,0 +1,373 @@
// 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 "primitives_view.h"
#include "primitive_item.h"
#include "primitives_model.h"
#include "world_editor_actions.h"
#include "../core/core_constants.h"
#include "../landscape_editor/landscape_editor_constants.h"
#include "../landscape_editor/builder_zone_base.h"
// NeL includes
#include <nel/ligo/primitive.h>
#include <nel/ligo/ligo_config.h>
#include <nel/ligo/primitive_class.h>
// Qt includes
#include <QContextMenuEvent>
#include <QtGui/QMenu>
#include <QtGui/QFileDialog>
namespace WorldEditor
{
PrimitivesView::PrimitivesView(QWidget *parent)
: QTreeView(parent),
m_undoStack(0),
m_zoneBuilder(0),
m_primitivesTreeModel(0)
{
setContextMenuPolicy(Qt::DefaultContextMenu);
m_unloadAction = new QAction("Unload", this);
m_unloadAction->setEnabled(false);
m_saveAction = new QAction("Save", this);
m_saveAction->setEnabled(false);
m_saveAction->setIcon(QIcon(Core::Constants::ICON_SAVE));
m_saveAsAction = new QAction("Save As...", this);
m_saveAsAction->setIcon(QIcon(Core::Constants::ICON_SAVE_AS));
m_saveAsAction->setEnabled(false);
m_loadLandAction = new QAction("Load landscape file", this);
m_loadLandAction->setIcon(QIcon(LandscapeEditor::Constants::ICON_ZONE_ITEM));
m_loadPrimitiveAction = new QAction("Load primitive file", this);
m_loadPrimitiveAction->setIcon(QIcon("./old_ico/root.ico"));
m_newPrimitiveAction = new QAction("New primitive", this);
m_deleteAction = new QAction("Delete", this);
m_deleteAction->setEnabled(false);
m_selectChildrenAction = new QAction("Select children", this);
m_helpAction = new QAction("Help", this);
m_helpAction->setEnabled(false);
m_showAction = new QAction("Show", this);
m_showAction->setEnabled(false);
m_hideAction = new QAction("Hide", this);
m_hideAction->setEnabled(false);
connect(m_loadLandAction, SIGNAL(triggered()), this, SLOT(loadLandscape()));
connect(m_loadPrimitiveAction, SIGNAL(triggered()), this, SLOT(loadRootPrimitive()));
connect(m_newPrimitiveAction, SIGNAL(triggered()), this, SLOT(createRootPrimitive()));
connect(m_selectChildrenAction, SIGNAL(triggered()), this, SLOT(selectChildren()));
connect(m_deleteAction, SIGNAL(triggered()), this, SLOT(deletePrimitives()));
#ifdef Q_OS_DARWIN
setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
#endif
}
PrimitivesView::~PrimitivesView()
{
}
void PrimitivesView::setUndoStack(QUndoStack *undoStack)
{
m_undoStack = undoStack;
}
void PrimitivesView::setZoneBuilder(LandscapeEditor::ZoneBuilderBase *zoneBuilder)
{
m_zoneBuilder = zoneBuilder;
}
void PrimitivesView::setModel(PrimitivesTreeModel *model)
{
QTreeView::setModel(model);
m_primitivesTreeModel = model;
}
void PrimitivesView::loadRootPrimitive()
{
nlassert(m_undoStack);
nlassert(m_primitivesTreeModel);
QStringList fileNames = QFileDialog::getOpenFileNames(this,
tr("Open NeL Ligo primitive file"), m_lastDir,
tr("All NeL Ligo primitive files (*.primitive)"));
setCursor(Qt::WaitCursor);
if (!fileNames.isEmpty())
{
if (fileNames.count() > 1)
m_undoStack->beginMacro("Load primitive files");
Q_FOREACH(QString fileName, fileNames)
{
m_lastDir = QFileInfo(fileName).absolutePath();
m_undoStack->push(new LoadRootPrimitiveCommand(fileName, m_primitivesTreeModel));
}
if (fileNames.count() > 1)
m_undoStack->endMacro();
}
setCursor(Qt::ArrowCursor);
}
void PrimitivesView::loadLandscape()
{
nlassert(m_undoStack);
nlassert(m_zoneBuilder);
nlassert(m_primitivesTreeModel);
QStringList fileNames = QFileDialog::getOpenFileNames(this,
tr("Open NeL Ligo land file"), m_lastDir,
tr("All NeL Ligo land files (*.land)"));
setCursor(Qt::WaitCursor);
if (!fileNames.isEmpty())
{
if (fileNames.count() > 1)
m_undoStack->beginMacro("Load land files");
Q_FOREACH(QString fileName, fileNames)
{
m_lastDir = QFileInfo(fileName).absolutePath();
m_undoStack->push(new LoadLandscapeCommand(fileName, m_primitivesTreeModel, m_zoneBuilder));
}
if (fileNames.count() > 1)
m_undoStack->endMacro();
}
setCursor(Qt::ArrowCursor);
}
void PrimitivesView::createRootPrimitive()
{
nlassert(m_undoStack);
nlassert(m_primitivesTreeModel);
m_undoStack->push(new CreateRootPrimitiveCommand("NewPrimitive", m_primitivesTreeModel));
}
void PrimitivesView::selectChildren()
{
QModelIndexList indexList = selectionModel()->selectedRows();
QModelIndex parentIndex = indexList.first();
selectionModel()->clearSelection();
selectChildren(parentIndex);
}
void PrimitivesView::deletePrimitives()
{
nlassert(m_undoStack);
nlassert(m_primitivesTreeModel);
QModelIndexList indexList = selectionModel()->selectedRows();
}
void PrimitivesView::addNewPrimitiveByClass(int value)
{
nlassert(m_undoStack);
nlassert(m_primitivesTreeModel);
QModelIndexList indexList = selectionModel()->selectedRows();
PrimitiveNode *node = static_cast<PrimitiveNode *>(indexList.first().internalPointer());
// Get class name
QString className = node->primitiveClass()->DynamicChildren[value].ClassName.c_str();
m_undoStack->push(new AddPrimitiveByClassCommand(className, m_primitivesTreeModel->pathFromIndex(indexList.first()),
m_primitivesTreeModel));
}
void PrimitivesView::generatePrimitives(int value)
{
}
void PrimitivesView::openItem(int value)
{
}
void PrimitivesView::contextMenuEvent(QContextMenuEvent *event)
{
QWidget::contextMenuEvent(event);
QModelIndexList indexList = selectionModel()->selectedRows();
if (indexList.size() == 0)
return;
QMenu *popurMenu = new QMenu(this);
if (indexList.size() == 1)
{
Node *node = static_cast<Node *>(indexList.first().internalPointer());
switch (node->type())
{
case Node::WorldEditNodeType:
fillMenu_WorldEdit(popurMenu);
break;
case Node::RootPrimitiveNodeType:
fillMenu_RootPrimitive(popurMenu, indexList.first());
break;
case Node::LandscapeNodeType:
fillMenu_Landscape(popurMenu);
break;
case Node::PrimitiveNodeType:
fillMenu_Primitive(popurMenu, indexList.first());
break;
};
}
popurMenu->exec(event->globalPos());
delete popurMenu;
event->accept();
}
void PrimitivesView::selectChildren(const QModelIndex &parent)
{
const int rowCount = model()->rowCount(parent);
for (int i = 0; i < rowCount; ++i)
{
QModelIndex childIndex = parent.child(i, 0);
selectionModel()->select(childIndex, QItemSelectionModel::Select);
selectChildren(childIndex);
}
}
void PrimitivesView::fillMenu_WorldEdit(QMenu *menu)
{
menu->addAction(m_unloadAction);
menu->addAction(m_saveAction);
menu->addAction(m_saveAsAction);
menu->addSeparator();
menu->addAction(m_loadLandAction);
menu->addAction(m_loadPrimitiveAction);
menu->addAction(m_newPrimitiveAction);
menu->addSeparator();
menu->addAction(m_helpAction);
}
void PrimitivesView::fillMenu_Landscape(QMenu *menu)
{
menu->addAction(m_deleteAction);
menu->addSeparator();
menu->addAction(m_showAction);
menu->addAction(m_hideAction);
}
void PrimitivesView::fillMenu_RootPrimitive(QMenu *menu, const QModelIndex &index)
{
menu->addAction(m_saveAction);
menu->addAction(m_saveAsAction);
fillMenu_Primitive(menu, index);
}
void PrimitivesView::fillMenu_Primitive(QMenu *menu, const QModelIndex &index)
{
menu->addAction(m_deleteAction);
menu->addAction(m_selectChildrenAction);
menu->addAction(m_helpAction);
menu->addSeparator();
menu->addAction(m_showAction);
menu->addAction(m_hideAction);
QSignalMapper *addSignalMapper = new QSignalMapper(menu);
QSignalMapper *generateSignalMapper = new QSignalMapper(menu);
QSignalMapper *openSignalMapper = new QSignalMapper(menu);
connect(addSignalMapper, SIGNAL(mapped(int)), this, SLOT(addNewPrimitiveByClass(int)));
connect(generateSignalMapper, SIGNAL(mapped(int)), this, SLOT(generatePrimitives(int)));
//connect(openSignalMapper, SIGNAL(mapped(int)), this, SLOT(openItem(int)));
PrimitiveNode *node = static_cast<PrimitiveNode *>(index.internalPointer());
const NLLIGO::CPrimitiveClass *primClass = node->primitiveClass();
// What class is it ?
if (primClass && primClass->DynamicChildren.size())
{
menu->addSeparator();
// For each child, add a create method
for (size_t i = 0; i < primClass->DynamicChildren.size(); i++)
{
// Get class name
QString className = primClass->DynamicChildren[i].ClassName.c_str();
// Get icon
QIcon icon(QString("./old_ico/%1.ico").arg(className));
// Create and add action in popur menu
QAction *action = menu->addAction(icon, QString("Add %1").arg(className));
addSignalMapper->setMapping(action, i);
connect(action, SIGNAL(triggered()), addSignalMapper, SLOT(map()));
}
}
// What class is it ?
if (primClass && primClass->GeneratedChildren.size())
{
menu->addSeparator();
// For each child, add a create method
for (size_t i = 0; i < primClass->GeneratedChildren.size(); i++)
{
// Get class name
QString childName = primClass->GeneratedChildren[i].ClassName.c_str();
// Create and add action in popur menu
QAction *action = menu->addAction(QString("Generate %1").arg(childName));
generateSignalMapper->setMapping(action, i);
connect(generateSignalMapper, SIGNAL(triggered()), addSignalMapper, SLOT(map()));
}
}
/*
// What class is it ?
if (primClass)
{
// Look for files
std::vector<std::string> filenames;
// Filenames
buildFilenameVector (*Selection.front (), filenames);
// File names ?
if (!filenames.empty ())
{
// Add separator
popurMenu->addSeparator();
// Found ?
for (uint i = 0; i < filenames.size(); i++)
{
// Add a menu entry
pMenu->AppendMenu (MF_STRING, ID_EDIT_OPEN_FILE_BEGIN+i, ("Open "+NLMISC::CFile::getFilename (filenames[i])).c_str ());
}
}
*/
}
} /* namespace WorldEditor */

View file

@ -0,0 +1,101 @@
// 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 PRIMITIVES_VIEW_H
#define PRIMITIVES_VIEW_H
// NeL includes
#include <nel/ligo/primitive.h>
// Qt includes
#include <QtGui/QAction>
#include <QtGui/QTreeView>
#include <QtCore/QModelIndex>
#include <QtCore/QVariant>
#include <QtCore/QSignalMapper>
#include <QPersistentModelIndex>
#include <QtGui/QUndoStack>
namespace LandscapeEditor
{
class ZoneBuilderBase;
}
namespace WorldEditor
{
class PrimitivesTreeModel;
/**
@class PrimitivesView
@brief
@details
*/
class PrimitivesView : public QTreeView
{
Q_OBJECT
public:
PrimitivesView(QWidget *parent = 0);
~PrimitivesView();
void setUndoStack(QUndoStack *undoStack);
void setZoneBuilder(LandscapeEditor::ZoneBuilderBase *zoneBuilder);
virtual void setModel(PrimitivesTreeModel *model);
private Q_SLOTS:
void loadLandscape();
void loadRootPrimitive();
void createRootPrimitive();
void selectChildren();
void deletePrimitives();
void addNewPrimitiveByClass(int value);
void generatePrimitives(int value);
void openItem(int value);
protected:
void contextMenuEvent(QContextMenuEvent *event);
private:
void selectChildren(const QModelIndex &parent);
void fillMenu_WorldEdit(QMenu *menu);
void fillMenu_Landscape(QMenu *menu);
void fillMenu_RootPrimitive(QMenu *menu, const QModelIndex &index);
void fillMenu_Primitive(QMenu *menu, const QModelIndex &index);
QString m_lastDir;
QAction *m_unloadAction;
QAction *m_saveAction;
QAction *m_saveAsAction;
QAction *m_loadLandAction;
QAction *m_loadPrimitiveAction;
QAction *m_newPrimitiveAction;
QAction *m_deleteAction;
QAction *m_selectChildrenAction;
QAction *m_helpAction;
QAction *m_showAction;
QAction *m_hideAction;
QUndoStack *m_undoStack;
LandscapeEditor::ZoneBuilderBase *m_zoneBuilder;
PrimitivesTreeModel *m_primitivesTreeModel;
};
} /* namespace WorldEditor */
#endif // PRIMITIVES_VIEW_H

View file

@ -0,0 +1,10 @@
<RCC>
<qresource prefix="/">
<file>icons/ic_nel_select.png</file>
<file>icons/ic_nel_scale.png</file>
<file>icons/ic_nel_rotate.png</file>
<file>icons/ic_nel_move.png</file>
<file>icons/ic_nel_turn.png</file>
<file>icons/ic_nel_world_editor.png</file>
</qresource>
</RCC>

View file

@ -0,0 +1,226 @@
// 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 "world_editor_actions.h"
#include "world_editor_misc.h"
#include "primitive_item.h"
// Lanscape Editor plugin
#include "../landscape_editor/builder_zone_base.h"
// STL includes
#include <string>
// NeL includes
#include <nel/misc/debug.h>
#include <nel/misc/path.h>
#include <nel/ligo/primitive_utils.h>
#include <nel/ligo/primitive.h>
#include <nel/misc/file.h>
// Qt includes
#include <QModelIndex>
namespace WorldEditor
{
CreateWorldCommand::CreateWorldCommand(const QString &fileName, PrimitivesTreeModel *model, QUndoCommand *parent)
: QUndoCommand(parent),
m_fileName(fileName),
m_model(model)
{
setText("Create new world");
}
CreateWorldCommand::~CreateWorldCommand()
{
}
void CreateWorldCommand::undo()
{
m_model->deleteWorldEditNode();
}
void CreateWorldCommand::redo()
{
m_model->createWorldEditNode(m_fileName);
}
LoadLandscapeCommand::LoadLandscapeCommand(const QString &fileName, PrimitivesTreeModel *model,
LandscapeEditor::ZoneBuilderBase *zoneBuilder, QUndoCommand *parent)
: QUndoCommand(parent),
m_id(-1),
m_fileName(fileName),
m_model(model),
m_zoneBuilder(zoneBuilder)
{
setText("Load land file");
}
LoadLandscapeCommand::~LoadLandscapeCommand()
{
}
void LoadLandscapeCommand::undo()
{
m_zoneBuilder->deleteZoneRegion(m_id);
m_model->deleteNode(landIndex);
}
void LoadLandscapeCommand::redo()
{
if (m_id == -1)
m_id = m_zoneBuilder->loadZoneRegion(m_fileName);
else
m_zoneBuilder->loadZoneRegion(m_fileName, m_id);
landIndex = m_model->createLandscapeNode(m_fileName);
}
CreateRootPrimitiveCommand::CreateRootPrimitiveCommand(const QString &fileName, PrimitivesTreeModel *model, QUndoCommand *parent)
: QUndoCommand(parent),
m_fileName(fileName),
m_model(model)
{
setText("Create new primitive");
}
CreateRootPrimitiveCommand::~CreateRootPrimitiveCommand()
{
}
void CreateRootPrimitiveCommand::undo()
{
QModelIndex index = m_model->pathToIndex(m_rootPrimIndex);
RootPrimitiveNode *node = static_cast<RootPrimitiveNode *>(index.internalPointer());
delete node->primitives();
m_model->deleteNode(m_rootPrimIndex);
}
void CreateRootPrimitiveCommand::redo()
{
NLLIGO::CPrimitives *newRootPrim = new NLLIGO::CPrimitives();
m_rootPrimIndex = m_model->createRootPrimitiveNode(m_fileName, newRootPrim);
}
LoadRootPrimitiveCommand::LoadRootPrimitiveCommand(const QString &fileName, PrimitivesTreeModel *model, QUndoCommand *parent)
: QUndoCommand(parent),
m_fileName(fileName),
m_model(model)
{
setText("Load primitive file");
}
LoadRootPrimitiveCommand::~LoadRootPrimitiveCommand()
{
}
void LoadRootPrimitiveCommand::undo()
{
QModelIndex index = m_model->pathToIndex(m_rootPrimIndex);
RootPrimitiveNode *node = static_cast<RootPrimitiveNode *>(index.internalPointer());
delete node->primitives();
m_model->deleteNode(m_rootPrimIndex);
}
void LoadRootPrimitiveCommand::redo()
{
NLLIGO::CPrimitives *primitives = new NLLIGO::CPrimitives();
// set the primitive context
NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = primitives;
NLLIGO::loadXmlPrimitiveFile(*primitives, m_fileName.toStdString(), *NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig);
// unset the context
NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = NULL;
// Initialize default values
Utils::recursiveUpdateDefaultValues(primitives->RootNode);
// Check property types
if (Utils::recursiveUpdateDefaultValues(primitives->RootNode))
{
nlwarning("In file (%s) : Some primitives have been modified to initialise their default values\nor to change their properties type.", m_fileName.toStdString().c_str());
}
m_rootPrimIndex = m_model->createRootPrimitiveNode(m_fileName, primitives);
}
AddPrimitiveByClassCommand::AddPrimitiveByClassCommand(const QString &className, const Path &parentIndex,
PrimitivesTreeModel *model, QUndoCommand *parent)
: QUndoCommand(parent),
m_className(className),
m_parentIndex(parentIndex),
m_model(model)
{
setText(QString("Add %1").arg(m_className));
}
AddPrimitiveByClassCommand::~AddPrimitiveByClassCommand()
{
}
void AddPrimitiveByClassCommand::undo()
{
QModelIndex index = m_model->pathToIndex(m_newPrimIndex);
PrimitiveNode *node = static_cast<PrimitiveNode *>(index.internalPointer());
// set the primitive context
NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = node->rootPrimitiveNode()->primitives();
Utils::deletePrimitive(node->primitive());
// unset the context
NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = NULL;
m_model->deleteNode(m_newPrimIndex);
}
void AddPrimitiveByClassCommand::redo()
{
QModelIndex parentIndex = m_model->pathToIndex(m_parentIndex);
PrimitiveNode *parentNode = static_cast<PrimitiveNode *>(parentIndex.internalPointer());
const NLLIGO::CPrimitiveClass *primClass = parentNode->primitiveClass();
float delta = 10;
int id = 0;
while (primClass->DynamicChildren[id].ClassName != m_className.toStdString())
++id;
// set the primitive context
NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = parentNode->rootPrimitiveNode()->primitives();
QString namePrimititve = QString("%1_%2").arg(m_className).arg(parentNode->childCount());
NLLIGO::IPrimitive *newPrimitive = Utils::createPrimitive(m_className.toStdString().c_str(), namePrimititve.toStdString().c_str(),
NLMISC::CVector(), delta, primClass->DynamicChildren[id].Parameters, parentNode->primitive());
// unset the context
NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = NULL;
m_newPrimIndex = m_model->createPrimitiveNode(newPrimitive, m_parentIndex);
}
} /* namespace WorldEditor */

View file

@ -0,0 +1,138 @@
// 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 WORLD_EDITOR_ACTIONS_H
#define WORLD_EDITOR_ACTIONS_H
// Project includes
#include "primitives_model.h"
// NeL includes
// Qt includes
#include <QtGui/QUndoCommand>
#include <QtGui/QGraphicsScene>
#include <QtGui/QGraphicsItem>
namespace LandscapeEditor
{
class ZoneBuilderBase;
}
namespace WorldEditor
{
/**
@class CreateWorldCommand
@brief
@details
*/
class CreateWorldCommand: public QUndoCommand
{
public:
CreateWorldCommand(const QString &fileName, PrimitivesTreeModel *model, QUndoCommand *parent = 0);
virtual ~CreateWorldCommand();
virtual void undo();
virtual void redo();
private:
const QString m_fileName;
PrimitivesTreeModel *const m_model;
};
/**
@class LoadLandscapeCommand
@brief
@details
*/
class LoadLandscapeCommand: public QUndoCommand
{
public:
LoadLandscapeCommand(const QString &fileName, PrimitivesTreeModel *model,
LandscapeEditor::ZoneBuilderBase *zoneBuilder, QUndoCommand *parent = 0);
virtual ~LoadLandscapeCommand();
virtual void undo();
virtual void redo();
private:
Path landIndex;
int m_id;
const QString m_fileName;
PrimitivesTreeModel *const m_model;
LandscapeEditor::ZoneBuilderBase *const m_zoneBuilder;
};
class CreateRootPrimitiveCommand: public QUndoCommand
{
public:
CreateRootPrimitiveCommand(const QString &fileName, PrimitivesTreeModel *model, QUndoCommand *parent = 0);
virtual ~CreateRootPrimitiveCommand();
virtual void undo();
virtual void redo();
private:
const QString m_fileName;
Path m_rootPrimIndex;
PrimitivesTreeModel *const m_model;
};
/**
@class LoadPrimitiveCommand
@brief
@details
*/
class LoadRootPrimitiveCommand: public QUndoCommand
{
public:
LoadRootPrimitiveCommand(const QString &fileName, PrimitivesTreeModel *model, QUndoCommand *parent = 0);
virtual ~LoadRootPrimitiveCommand();
virtual void undo();
virtual void redo();
private:
Path m_rootPrimIndex;
const QString m_fileName;
PrimitivesTreeModel *const m_model;
};
/**
@class AddPrimitiveCommand
@brief
@details
*/
class AddPrimitiveByClassCommand: public QUndoCommand
{
public:
AddPrimitiveByClassCommand(const QString &className, const Path &parentIndex,
PrimitivesTreeModel *model, QUndoCommand *parent = 0);
virtual ~AddPrimitiveByClassCommand();
virtual void undo();
virtual void redo();
private:
const QString m_className;
Path m_parentIndex, m_newPrimIndex;
PrimitivesTreeModel *m_model;
};
} /* namespace WorldEditor */
#endif // WORLD_EDITOR_ACTIONS_H

View file

@ -0,0 +1,43 @@
// 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 WORLD_EDITOR_CONSTANTS_H
#define WORLD_EDITOR_CONSTANTS_H
namespace WorldEditor
{
namespace Constants
{
const char *const WORLD_EDITOR_PLUGIN = "WorldEditor";
//settings
const char *const WORLD_EDITOR_SECTION = "WorldEditor";
const char *const WORLD_WINDOW_STATE = "WorldWindowState";
const char *const WORLD_WINDOW_GEOMETRY = "WorldWindowGeometry";
const char *const WORLD_EDITOR_CELL_SIZE = "WorldEditorCellSize";
const char *const WORLD_EDITOR_SNAP = "WorldEditorSnap";
const char *const ZONE_SNAPSHOT_RES = "WorldEditorZoneSnapshotRes";
const char *const PRIMITIVE_CLASS_FILENAME = "WorldEditorPrimitiveClassFilename";
//resources
const char *const ICON_WORLD_EDITOR = ":/icons/ic_nel_world_editor.png";
} // namespace Constants
} // namespace WorldEditor
#endif // WORLD_EDITOR_CONSTANTS_H

View file

@ -0,0 +1,30 @@
// 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>
// Parts by Nokia Corporation (qt-info@nokia.com) Copyright (C) 2009.
//
// 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 WORLD_EDITOR_GLOBAL_H
#define WORLD_EDITOR_GLOBAL_H
#include <QtCore/qglobal.h>
#if defined(WORLD_EDITOR_LIBRARY)
# define WORLD_EDITOR_EXPORT Q_DECL_EXPORT
#else
# define WORLD_EDITOR_EXPORT Q_DECL_IMPORT
#endif
#endif // WORLD_EDITOR_GLOBAL_H

View file

@ -0,0 +1,692 @@
// 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 "world_editor_misc.h"
// NeL includes
#include <nel/misc/debug.h>
#include <nel/misc/path.h>
#include <nel/misc/file.h>
#include <nel/misc/i_xml.h>
#include <nel/misc/o_xml.h>
#include <nel/ligo/primitive_utils.h>
#include <nel/ligo/ligo_config.h>
// Qt includes
namespace WorldEditor
{
namespace Utils
{
void syntaxError(const char *filename, xmlNodePtr xmlNode, const char *format, ...)
{
char buffer[1024];
if (format)
{
va_list args;
va_start( args, format );
sint ret = vsnprintf( buffer, 1024, format, args );
va_end( args );
}
else
{
strcpy(buffer, "Unknown error");
}
nlerror("(%s), node (%s), line (%d) :\n%s", filename, xmlNode->name, (int)xmlNode->content, buffer);
}
bool getPropertyString(std::string &result, const char *filename, xmlNodePtr xmlNode, const char *propName)
{
// Call the CIXml version
if (!NLMISC::CIXml::getPropertyString(result, xmlNode, propName))
{
// Output a formated error
syntaxError(filename, xmlNode, "Missing XML node property (%s)", propName);
return false;
}
return true;
}
uint32 getUniqueId()
{
// Wait 1 ms
sint64 time = NLMISC::CTime::getLocalTime ();
sint64 time2;
while ((time2 = NLMISC::CTime::getLocalTime ()) == time)
{
}
return (uint32)time2;
}
bool loadWorldEditFile(const std::string &fileName, WorldEditList &worldEditList)
{
bool result = false;
// Load the document
NLMISC::CIFile file;
if (file.open(fileName))
{
try
{
// Load the document in XML
NLMISC::CIXml xml;
xml.init(file);
// Get root node
xmlNodePtr rootNode = xml.getRootNode();
if (rootNode)
{
// Good header ?
if (strcmp((const char *)(rootNode->name), "NEL_WORLD_EDITOR_PROJECT") == 0)
{
// Read the version
int version = -1;
// Read the parameters
xmlNodePtr node = NLMISC::CIXml::getFirstChildNode(rootNode, "VERSION");
if (node)
{
std::string versionString;
if (NLMISC::CIXml::getContentString (versionString, node))
version = atoi(versionString.c_str ());
}
if (version == -1)
{
// Error
syntaxError(fileName.c_str(), rootNode, "No version node");
}
else
{
// Old format,
if (version <= 1)
{
syntaxError(fileName.c_str(), rootNode, "Old version node");
}
else
{
// Read it
if (version > WORLD_EDITOR_FILE_VERSION)
{
syntaxError(fileName.c_str(), node, "Unknown file version");
}
else
{
// Read data directory
node = NLMISC::CIXml::getFirstChildNode(rootNode, "DATA_DIRECTORY");
if (node)
{
std::string dataDir;
NLMISC::CIXml::getPropertyString(dataDir, node, "VALUE");
worldEditList.push_back(WorldEditItem(DataDirectoryType, dataDir));
}
// Read data directory
node = NLMISC::CIXml::getFirstChildNode(rootNode, "CONTEXT");
if (node)
{
std::string context;
NLMISC::CIXml::getPropertyString(context, node, "VALUE");
worldEditList.push_back(WorldEditItem(ContextType, context));
}
// Read the database element
node = NLMISC::CIXml::getFirstChildNode(rootNode, "DATABASE_ELEMENT");
if (node)
{
do
{
// Get the type
std::string type;
if (getPropertyString(type, fileName.c_str(), node, "TYPE"))
{
// Read the filename
std::string filenameChild;
if (getPropertyString(filenameChild, fileName.c_str(), node, "FILENAME"))
{
// Is it a landscape ?
if (type == "landscape")
{
worldEditList.push_back(WorldEditItem(LandscapeType, filenameChild));
// Get the primitives
xmlNodePtr primitives = NLMISC::CIXml::getFirstChildNode(node, "PRIMITIVES");
if (primitives)
{
NLLIGO::CPrimitives ligoPrimitives;
// Read it
ligoPrimitives.read(primitives, fileName.c_str(), *NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig);
//_DataHierarchy.back ().Primitives.read (primitives, filename, theApp.Config);
// Set the filename
//_DataHierarchy.back ().Filename = filenameChild;
}
}
else
{
worldEditList.push_back(WorldEditItem(PrimitiveType, filenameChild));
}
}
}
}
while (node = NLMISC::CIXml::getNextChildNode(node, "DATABASE_ELEMENT"));
}
// Done
result = true;
}
}
}
}
else
{
// Error
syntaxError(fileName.c_str(), rootNode, "Unknown file header : %s", rootNode->name);
}
}
}
catch (NLMISC::Exception &e)
{
nlerror("Error reading file %s : %s", fileName.c_str(), e.what());
}
}
else
{
nlerror("Can't open the file %s for reading.", fileName.c_str());
}
return result;
}
NLLIGO::IPrimitive *getRootPrimitive(NLLIGO::IPrimitive *primitive)
{
nlassert(primitive);
if (primitive->getParent() == NULL)
return primitive;
else
return getRootPrimitive(primitive->getParent());
}
void initPrimitiveParameters(const NLLIGO::CPrimitiveClass &primClass, NLLIGO::IPrimitive &primitive,
const std::vector<NLLIGO::CPrimitiveClass::CInitParameters> &initParameters)
{
// Other parameters
for (uint p = 0; p < initParameters.size(); ++p)
{
// The property
const NLLIGO::CPrimitiveClass::CInitParameters &parameter = initParameters[p];
// Look for it in the class
uint cp;
for (cp = 0; cp < primClass.Parameters.size(); ++cp)
{
// Good one ?
if (primClass.Parameters[cp].Name == initParameters[p].Name)
break;
}
// The primitive type
NLLIGO::CPrimitiveClass::CParameter::TType type;
// Found ?
if (cp < primClass.Parameters.size())
type = primClass.Parameters[cp].Type;
// Name ?
if (initParameters[p].Name == "name")
type = NLLIGO::CPrimitiveClass::CParameter::String;
// Continue ?
if (cp<primClass.Parameters.size () || (initParameters[p].Name == "name"))
{
// Default value ?
if (!parameter.DefaultValue.empty())
{
// Type of property
switch (type)
{
case NLLIGO::CPrimitiveClass::CParameter::Boolean:
case NLLIGO::CPrimitiveClass::CParameter::ConstString:
case NLLIGO::CPrimitiveClass::CParameter::String:
{
// Some feedback
if (parameter.DefaultValue.size() > 1)
nlerror("Warning: parameter (%s) in class name (%s) has more than 1 default value (%d).",
parameter.Name.c_str(), primClass.Name.c_str(), parameter.DefaultValue.size());
if ((cp < primClass.Parameters.size() && !primClass.Parameters[cp].Visible)
|| parameter.DefaultValue[0].GenID)
{
// Remove this property
primitive.removePropertyByName(parameter.Name.c_str());
// Add this property
primitive.addPropertyByName(parameter.Name.c_str(),
new NLLIGO::CPropertyString((parameter.DefaultValue[0].GenID ? NLMISC::toString(getUniqueId()) : "").c_str ()));
}
break;
}
case NLLIGO::CPrimitiveClass::CParameter::ConstStringArray:
case NLLIGO::CPrimitiveClass::CParameter::StringArray:
{
bool Visible = false;
if (cp < primClass.Parameters.size() && !primClass.Parameters[cp].Visible)
{
Visible = true;
}
for (size_t i = 0; i < parameter.DefaultValue.size(); ++i)
{
// Generate a unique id ?
if (parameter.DefaultValue[i].GenID)
{
Visible = true;
}
}
if (Visible)
{
// Remove this property
primitive.removePropertyByName (parameter.Name.c_str());
// Add this property
NLLIGO::CPropertyStringArray *str = new NLLIGO::CPropertyStringArray();
str->StringArray.resize (parameter.DefaultValue.size());
for (size_t i = 0; i < parameter.DefaultValue.size(); ++i)
{
// Generate a unique id ?
if (parameter.DefaultValue[i].GenID)
{
str->StringArray[i] = NLMISC::toString(getUniqueId());
}
else
{
str->StringArray[i] = "";
}
}
primitive.addPropertyByName(parameter.Name.c_str(), str);
}
break;
}
}
}
}
else
{
// Some feedback
nlerror("Warning: parameter (%s) doesn't exist in class (%s).",
initParameters[p].Name.c_str(), primClass.Name.c_str());
}
}
}
NLLIGO::IPrimitive *createPrimitive(const char *className, const char *primName,
const NLMISC::CVector &initPos, float deltaPos,
const std::vector<NLLIGO::CPrimitiveClass::CInitParameters> &initParameters,
NLLIGO::IPrimitive *parent)
{
// Get the prim class
const NLLIGO::CPrimitiveClass *primClass = NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig->getPrimitiveClass(className);
if (primClass)
{
// Create the base primitive
NLLIGO::IPrimitive *primitive = NULL;
switch (primClass->Type)
{
case NLLIGO::CPrimitiveClass::Node:
primitive = new NLLIGO::CPrimNode;
break;
case NLLIGO::CPrimitiveClass::Point:
{
NLLIGO::CPrimPoint *point = new NLLIGO::CPrimPoint;
primitive = point;
point->Point.CVector::operator = (initPos);
}
break;
case NLLIGO::CPrimitiveClass::Path:
primitive = new NLLIGO::CPrimPath;
break;
case NLLIGO::CPrimitiveClass::Zone:
primitive = new NLLIGO::CPrimZone;
break;
case NLLIGO::CPrimitiveClass::Alias:
primitive = new NLLIGO::CPrimAlias;
break;
case NLLIGO::CPrimitiveClass::Bitmap:
primitive = new NLLIGO::CPrimNode;
break;
}
nlassert(primitive);
// Add properties
primitive->addPropertyByName("class", new NLLIGO::CPropertyString(className));
primitive->addPropertyByName("name", new NLLIGO::CPropertyString(primName, primName[0] == 0));
// Init with default parameters
std::vector<NLLIGO::CPrimitiveClass::CInitParameters> tempParam;
tempParam.reserve(primClass->Parameters.size());
for (size_t i = 0; i < primClass->Parameters.size(); i++)
tempParam.push_back (primClass->Parameters[i]);
initPrimitiveParameters (*primClass, *primitive, tempParam);
// Init with option parameters
initPrimitiveParameters(*primClass, *primitive, initParameters);
parent->insertChild(primitive);
/*
// Insert the primitive
insertPrimitive (locator, primitive);
*/
// The new pos
NLMISC::CVector newPos = initPos;
newPos.x += deltaPos;
// Create static children
uint c;
for (c = 0; c < primClass->StaticChildren.size(); c++)
{
// The child ref
const NLLIGO::CPrimitiveClass::CChild &child = primClass->StaticChildren[c];
// Create the child
const NLLIGO::IPrimitive *childPrim = createPrimitive(child.ClassName.c_str(), child.Name.c_str(),
newPos, deltaPos, primClass->StaticChildren[c].Parameters, primitive);
// The new pos
newPos.y += deltaPos;
}
// Canceled ?
if (c < primClass->StaticChildren.size())
{
deletePrimitive(primitive);
return NULL;
}
// Prim file ?
if (primClass->Type == NLLIGO::CPrimitiveClass::Bitmap)
{
// Create a dialog file
//CFileDialogEx dialog (BASE_REGISTRY_KEY, "image", TRUE, primClass->FileExtension.c_str (), NULL, OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,
// (primClass->FileType+" (*."+primClass->FileExtension+")|*."+primClass->FileExtension+"|All Files (*.*)|*.*||").c_str (), getMainFrame ());
//if (dialog.DoModal() == IDOK)
//{
// Save filename
// static_cast<CPrimBitmap*>(primitive)->init(dialog.GetPathName ());
//}
}
// Continue ?
if (primitive)
{
// Auto init ?
if (!primClass->AutoInit)
{
// Make a vector of locator
//CDatabaseLocatorPointer locatorPtr;
//getLocator (locatorPtr, locator);
std::list<NLLIGO::IPrimitive *> locators;
//locators.push_back (const_cast<IPrimitive*> (locatorPtr.Primitive));
// Yes, go
//CDialogProperties dialogProperty (locators, getMainFrame ());
//dialogProperty.DoModal ();
}
// Eval the default name property
std::string name;
if (!primitive->getPropertyByName ("name", name) || name.empty())
{
const NLLIGO::CPrimitiveClass *primClass = NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig->getPrimitiveClass(*primitive);
if (primClass)
{
for (size_t i = 0; i < primClass->Parameters.size(); ++i)
{
if (primClass->Parameters[i].Name == "name")
{
std::string result;
primClass->Parameters[i].getDefaultValue(result, *primitive, *primClass, NULL);
if (!result.empty())
{
primitive->removePropertyByName("name");
primitive->addPropertyByName("name", new NLLIGO::CPropertyString(result.c_str(), true));
}
}
}
}
}
// Init primitive default values
primitive->initDefaultValues(*NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig);
}
// Done
return primitive;
}
else
{
nlerror("Unknown primitive class name : %s", className);
}
return 0;
}
void deletePrimitive(NLLIGO::IPrimitive *primitive)
{
// Get the parent
NLLIGO::IPrimitive *parent = primitive->getParent();
nlassert(parent);
// Get the child id
uint childId;
nlverify(parent->getChildId(childId, primitive));
// Delete the child
nlverify(parent->removeChild(childId));
}
bool updateDefaultValues(NLLIGO::IPrimitive *primitive)
{
// Modified
bool modified = false;
// Get the prim class
const NLLIGO::CPrimitiveClass *primClass = NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig->getPrimitiveClass(*primitive);
nlassert(primClass);
if (primClass)
{
// For each parameters
for (uint i = 0; i < primClass->Parameters.size(); i++)
{
// First check the primitive property has to good type
NLLIGO::IProperty *prop;
if (primitive->getPropertyByName(primClass->Parameters[i].Name.c_str(), prop))
{
// String to array ?
NLLIGO::CPropertyString *propString = dynamic_cast<NLLIGO::CPropertyString *>(prop);
const bool classStringArray = primClass->Parameters[i].Type == NLLIGO::CPrimitiveClass::CParameter::StringArray ||
primClass->Parameters[i].Type == NLLIGO::CPrimitiveClass::CParameter::ConstStringArray;
if (propString && classStringArray)
{
// Build an array string
std::vector<std::string> strings;
if (!propString->String.empty())
strings.push_back(propString->String);
prop = new NLLIGO::CPropertyStringArray(strings);
primitive->removePropertyByName(primClass->Parameters[i].Name.c_str());
primitive->addPropertyByName(primClass->Parameters[i].Name.c_str(), prop);
modified = true;
}
// Array to string ?
NLLIGO::CPropertyStringArray *propStringArray = dynamic_cast<NLLIGO::CPropertyStringArray *>(prop);
if (propStringArray && !classStringArray)
{
// Build an array string
std::string str;
if (!propStringArray->StringArray.empty())
str = propStringArray->StringArray[0];
prop = new NLLIGO::CPropertyString(str);
primitive->removePropertyByName(primClass->Parameters[i].Name.c_str());
primitive->addPropertyByName(primClass->Parameters[i].Name.c_str(), prop);
modified = true;
}
}
// String or string array ?
if (primClass->Parameters[i].Type == NLLIGO::CPrimitiveClass::CParameter::String)
{
// Default value available ?
if (!primClass->Parameters[i].DefaultValue.empty ())
{
// Unique Id ?
if (primClass->Parameters[i].DefaultValue[0].GenID)
{
// The doesn't exist ?
std::string result;
if (!primitive->getPropertyByName(primClass->Parameters[i].Name.c_str(), result))
{
// Add it !
primitive->addPropertyByName(primClass->Parameters[i].Name.c_str(), new NLLIGO::CPropertyString(NLMISC::toString(getUniqueId()).c_str()));
modified = true;
}
}
// Hidden ?
else if (!primClass->Parameters[i].Visible)
{
// The doesn't exist ?
std::string result;
if (!primitive->getPropertyByName (primClass->Parameters[i].Name.c_str (), result))
{
// Add it !
primitive->addPropertyByName (primClass->Parameters[i].Name.c_str (), new NLLIGO::CPropertyString (""));
modified = true;
}
}
}
}
else if ((primClass->Parameters[i].Type == NLLIGO::CPrimitiveClass::CParameter::StringArray) ||
(primClass->Parameters[i].Type == NLLIGO::CPrimitiveClass::CParameter::ConstStringArray))
{
for (uint j = 0; j < primClass->Parameters[i].DefaultValue.size(); j++)
{
// Unique Id ?
if (primClass->Parameters[i].DefaultValue[j].GenID)
{
// The doesn't exist ?
std::vector<std::string> result;
std::vector<std::string> *resultPtr = NULL;
if (!primitive->getPropertyByName(primClass->Parameters[i].Name.c_str(), resultPtr) ||
(resultPtr->size() <= j))
{
// Copy
if (resultPtr)
result = *resultPtr;
// Resize
if (result.size() <= j)
result.resize(j + 1);
// Resize to it
primitive->removePropertyByName(primClass->Parameters[i].Name.c_str());
// Set the value
result[j] = NLMISC::toString(getUniqueId());
// Add the new property array
primitive->addPropertyByName(primClass->Parameters[i].Name.c_str(), new NLLIGO::CPropertyStringArray(result));
modified = true;
}
}
// Hidden ?
else if (!primClass->Parameters[i].Visible)
{
// The doesn't exist ?
std::vector<std::string> result;
std::vector<std::string> *resultPtr = NULL;
if (!primitive->getPropertyByName(primClass->Parameters[i].Name.c_str(), resultPtr) || (resultPtr->size () <= j))
{
// Copy
if (resultPtr)
result = *resultPtr;
// Resize
if (result.size() <= j)
result.resize(j + 1);
// Resize to it
primitive->removePropertyByName(primClass->Parameters[i].Name.c_str());
// Set the value
result[j] = "";
// Add the new property array
primitive->addPropertyByName(primClass->Parameters[i].Name.c_str(), new NLLIGO::CPropertyStringArray(result));
modified = true;
}
}
}
}
else
{
// Default value available ?
if (!primClass->Parameters[i].DefaultValue.empty ())
{
// Hidden ?
if (!primClass->Parameters[i].Visible)
{
// The doesn't exist ?
std::string result;
if (!primitive->getPropertyByName(primClass->Parameters[i].Name.c_str(), result))
{
// Add it !
primitive->addPropertyByName(primClass->Parameters[i].Name.c_str(), new NLLIGO::CPropertyString(""));
modified = true;
}
}
}
}
}
}
return modified;
}
bool recursiveUpdateDefaultValues(NLLIGO::IPrimitive *primitive)
{
bool modified = updateDefaultValues(primitive);
const uint count = primitive->getNumChildren();
for (uint i = 0; i < count; ++i)
{
// Get the child
NLLIGO::IPrimitive *child;
nlverify(primitive->getChild(child, i));
modified |= recursiveUpdateDefaultValues(child);
}
return modified;
}
} /* namespace Utils */
} /* namespace WorldEditor */

View file

@ -0,0 +1,80 @@
// 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 WORLD_EDITOR_MISC_H
#define WORLD_EDITOR_MISC_H
// Project includes
// NeL includes
#include <nel/misc/vector.h>
#include <nel/ligo/primitive.h>
#include <nel/ligo/primitive_class.h>
// STL includes
#include <string>
#include <vector>
#define WORLD_EDITOR_FILE_VERSION 2
#define WORLD_EDITOR_DATABASE_SIZE 100
namespace WorldEditor
{
namespace Utils
{
enum ItemType
{
DataDirectoryType = 0,
ContextType,
LandscapeType,
PrimitiveType
};
typedef std::pair<ItemType, std::string> WorldEditItem;
typedef std::vector<WorldEditItem> WorldEditList;
// Generate unique identificator
uint32 getUniqueId();
// Load *.worldedit file and return list primitives and landscapes.
bool loadWorldEditFile(const std::string &fileName, WorldEditList &worldEditList);
// Get root primitive
NLLIGO::IPrimitive *getRootPrimitive(NLLIGO::IPrimitive *primitive);
// Init a primitive parameters
void initPrimitiveParameters(const NLLIGO::CPrimitiveClass &primClass, NLLIGO::IPrimitive &primitive,
const std::vector<NLLIGO::CPrimitiveClass::CInitParameters> &initParameters);
NLLIGO::IPrimitive *createPrimitive(const char *className, const char *primName,
const NLMISC::CVector &initPos, float deltaPos,
const std::vector<NLLIGO::CPrimitiveClass::CInitParameters> &initParameters,
NLLIGO::IPrimitive *parent);
// Remove the primitive and don't delete it.
//void takeAtPrimitive(NLLIGO::IPrimitive *primitive);
void deletePrimitive(NLLIGO::IPrimitive *primitive);
bool updateDefaultValues(NLLIGO::IPrimitive *primitive);
bool recursiveUpdateDefaultValues(NLLIGO::IPrimitive *primitive);
} /* namespace Utils */
} /* namespace WorldEditor */
#endif // WORLD_EDITOR_MISC_H

View file

@ -0,0 +1,158 @@
// 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 "world_editor_plugin.h"
#include "world_editor_window.h"
#include "../core/icore.h"
#include "../core/core_constants.h"
// NeL includes
#include "nel/misc/debug.h"
#include <nel/misc/path.h>
#include <nel/ligo/primitive_utils.h>
#include <nel/ligo/primitive.h>
// Qt includes
#include <QtCore/QObject>
namespace WorldEditor
{
WorldEditorPlugin::~WorldEditorPlugin()
{
Q_FOREACH(QObject *obj, m_autoReleaseObjects)
{
m_plugMan->removeObject(obj);
}
qDeleteAll(m_autoReleaseObjects);
m_autoReleaseObjects.clear();
}
bool WorldEditorPlugin::initialize(ExtensionSystem::IPluginManager *pluginManager, QString *errorString)
{
m_plugMan = pluginManager;
QSettings *settings = Core::ICore::instance()->settings();
settings->beginGroup(Constants::WORLD_EDITOR_SECTION);
m_ligoConfig.CellSize = settings->value(Constants::WORLD_EDITOR_CELL_SIZE, "160").toFloat();
m_ligoConfig.Snap = settings->value(Constants::WORLD_EDITOR_SNAP, "1").toFloat();
m_ligoConfig.ZoneSnapShotRes = settings->value(Constants::ZONE_SNAPSHOT_RES, "128").toUInt();
QString fileName = settings->value(Constants::PRIMITIVE_CLASS_FILENAME, "world_editor_classes.xml").toString();
settings->endGroup();
try
{
// Search path of file world_editor_classes.xml
std::string ligoPath = NLMISC::CPath::lookup(fileName.toStdString());
// Init LIGO
m_ligoConfig.readPrimitiveClass(ligoPath.c_str(), true);
NLLIGO::Register();
NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig = &m_ligoConfig;
}
catch (NLMISC::Exception &e)
{
*errorString = tr("(%1)").arg(e.what());
return false;
}
// Reset
m_ligoConfig.resetPrimitiveConfiguration ();
// Load
m_ligoConfig.readPrimitiveClass ("world_editor_primitive_configuration.xml", true);
addAutoReleasedObject(new WorldEditorContext(this));
return true;
}
void WorldEditorPlugin::extensionsInitialized()
{
}
void WorldEditorPlugin::shutdown()
{
}
void WorldEditorPlugin::setNelContext(NLMISC::INelContext *nelContext)
{
#ifdef NL_OS_WINDOWS
// Ensure that a context doesn't exist yet.
// This only applies to platforms without PIC, e.g. Windows.
nlassert(!NLMISC::INelContext::isContextInitialised());
#endif // NL_OS_WINDOWS
m_libContext = new NLMISC::CLibraryContext(*nelContext);
}
QString WorldEditorPlugin::name() const
{
return tr("WorldEditor");
}
QString WorldEditorPlugin::version() const
{
return "0.0.1";
}
QString WorldEditorPlugin::vendor() const
{
return "GSoC2011_dnk-88";
}
QString WorldEditorPlugin::description() const
{
return "World editor ovqt plugin.";
}
QStringList WorldEditorPlugin::dependencies() const
{
QStringList list;
list.append(Core::Constants::OVQT_CORE_PLUGIN);
return list;
}
void WorldEditorPlugin::addAutoReleasedObject(QObject *obj)
{
m_plugMan->addObject(obj);
m_autoReleaseObjects.prepend(obj);
}
WorldEditorContext::WorldEditorContext(QObject *parent)
: IContext(parent),
m_worldEditorWindow(0)
{
m_worldEditorWindow = new WorldEditorWindow();
}
QUndoStack *WorldEditorContext::undoStack()
{
return m_worldEditorWindow->undoStack();
}
void WorldEditorContext::open()
{
m_worldEditorWindow->open();
}
QWidget *WorldEditorContext::widget()
{
return m_worldEditorWindow;
}
}
Q_EXPORT_PLUGIN(WorldEditor::WorldEditorPlugin)

View file

@ -0,0 +1,110 @@
// 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 WORLD_EDITOR_PLUGIN_H
#define WORLD_EDITOR_PLUGIN_H
// Project includes
#include "world_editor_constants.h"
#include "../../extension_system/iplugin.h"
#include "../core/icontext.h"
// NeL includes
#include "nel/misc/app_context.h"
#include <nel/ligo/ligo_config.h>
// Qt includes
#include <QtCore/QObject>
#include <QtGui/QIcon>
namespace NLMISC
{
class CLibraryContext;
}
namespace ExtensionSystem
{
class IPluginSpec;
}
namespace WorldEditor
{
class WorldEditorWindow;
class WorldEditorPlugin : public QObject, public ExtensionSystem::IPlugin
{
Q_OBJECT
Q_INTERFACES(ExtensionSystem::IPlugin)
public:
virtual ~WorldEditorPlugin();
bool initialize(ExtensionSystem::IPluginManager *pluginManager, QString *errorString);
void extensionsInitialized();
void shutdown();
void setNelContext(NLMISC::INelContext *nelContext);
QString name() const;
QString version() const;
QString vendor() const;
QString description() const;
QStringList dependencies() const;
void addAutoReleasedObject(QObject *obj);
protected:
NLMISC::CLibraryContext *m_libContext;
private:
NLLIGO::CLigoConfig m_ligoConfig;
ExtensionSystem::IPluginManager *m_plugMan;
QList<QObject *> m_autoReleaseObjects;
};
class WorldEditorContext: public Core::IContext
{
Q_OBJECT
public:
WorldEditorContext(QObject *parent = 0);
virtual ~WorldEditorContext() {}
virtual QString id() const
{
return QLatin1String("WorldEditorContext");
}
virtual QString trName() const
{
return tr("World Editor");
}
virtual QIcon icon() const
{
return QIcon(Constants::ICON_WORLD_EDITOR);
}
virtual void open();
virtual QUndoStack *undoStack();
virtual QWidget *widget();
WorldEditorWindow *m_worldEditorWindow;
};
} // namespace WorldEditor
#endif // WORLD_EDITOR_PLUGIN_H

View file

@ -0,0 +1,71 @@
// 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 "world_editor_scene.h"
// NeL includes
#include <nel/misc/debug.h>
// Qt includes
#include <QtGui/QPainter>
#include <QtGui/QGraphicsPixmapItem>
#include <QtGui/QGraphicsSimpleTextItem>
#include <QApplication>
namespace WorldEditor
{
WorldEditorScene::WorldEditorScene(int sizeCell, QObject *parent)
: LandscapeEditor::LandscapeSceneBase(sizeCell, parent)
{
}
WorldEditorScene::~WorldEditorScene()
{
}
/*
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));
m_mouseButton = mouseEvent->button();
}
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);
}
void LandscapeSceneBase::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
QGraphicsScene::mouseReleaseEvent(mouseEvent);
m_mouseButton = Qt::NoButton;
}
*/
} /* namespace WorldEditor */

View file

@ -0,0 +1,57 @@
// 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 WORLD_EDITOR_SCENE_H
#define WORLD_EDITOR_SCENE_H
// Project includes
#include "world_editor_global.h"
#include "../landscape_editor/landscape_scene_base.h"
// NeL includes
// Qt includes
namespace WorldEditor
{
/*
@class WorldEditorScene
@brief
@details
*/
class WORLD_EDITOR_EXPORT WorldEditorScene : public LandscapeEditor::LandscapeSceneBase
{
Q_OBJECT
public:
WorldEditorScene(int sizeCell = 160, QObject *parent = 0);
virtual ~WorldEditorScene();
public Q_SLOTS:
protected:
// virtual void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent);
// virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent);
// virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent);
private:
};
} /* namespace WorldEditor */
#endif // WORLD_EDITOR_SCENE_H

View file

@ -0,0 +1,227 @@
// 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 "world_editor_window.h"
#include "world_editor_constants.h"
#include "primitives_model.h"
#include "world_editor_scene.h"
#include "world_editor_misc.h"
#include "world_editor_actions.h"
// Core
#include "../core/icore.h"
#include "../core/imenu_manager.h"
#include "../core/core_constants.h"
// Lanscape Editor plugin
#include "../landscape_editor/builder_zone_base.h"
// NeL includes
#include <nel/misc/path.h>
#include <nel/ligo/primitive_utils.h>
#include <nel/ligo/primitive.h>
#include <nel/ligo/ligo_config.h>
// Qt includes
#include <QtCore/QSettings>
#include <QtCore/QSignalMapper>
#include <QtGui/QFileDialog>
namespace WorldEditor
{
WorldEditorWindow::WorldEditorWindow(QWidget *parent)
: QMainWindow(parent),
m_primitivesModel(0),
m_undoStack(0)
{
m_ui.setupUi(this);
m_undoStack = new QUndoStack(this);
m_worldEditorScene = new WorldEditorScene(NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig->CellSize, this);
m_zoneBuilderBase = new LandscapeEditor::ZoneBuilderBase(m_worldEditorScene);
m_worldEditorScene->setZoneBuilder(m_zoneBuilderBase);
m_ui.graphicsView->setScene(m_worldEditorScene);
QActionGroup *sceneModeGroup = new QActionGroup(this);
sceneModeGroup->addAction(m_ui.selectAction);
sceneModeGroup->addAction(m_ui.moveAction);
sceneModeGroup->addAction(m_ui.rotateAction);
sceneModeGroup->addAction(m_ui.scaleAction);
sceneModeGroup->addAction(m_ui.turnAction);
sceneModeGroup->addAction(m_ui.radiusAction);
m_ui.selectAction->setChecked(true);
m_ui.newWorldEditAction->setIcon(QIcon(Core::Constants::ICON_NEW));
m_ui.saveWorldEditAction->setIcon(QIcon(Core::Constants::ICON_SAVE));
m_primitivesModel = new PrimitivesTreeModel();
m_ui.treePrimitivesView->setModel(m_primitivesModel);
// TODO: ?
m_ui.treePrimitivesView->setUndoStack(m_undoStack);
m_ui.treePrimitivesView->setZoneBuilder(m_zoneBuilderBase);
createMenus();
createToolBars();
readSettings();
connect(m_ui.newWorldEditAction, SIGNAL(triggered()), this, SLOT(newWorldEditFile()));
connect(m_ui.saveWorldEditAction, SIGNAL(triggered()), this, SLOT(saveWorldEditFile()));
}
WorldEditorWindow::~WorldEditorWindow()
{
writeSettings();
delete m_zoneBuilderBase;
}
QUndoStack *WorldEditorWindow::undoStack() const
{
return m_undoStack;
}
void WorldEditorWindow::open()
{
QString fileName = QFileDialog::getOpenFileName(this,
tr("Open NeL World Edit file"), m_lastDir,
tr("All NeL World Editor file (*.worldedit)"));
setCursor(Qt::WaitCursor);
if (!fileName.isEmpty())
{
m_lastDir = QFileInfo(fileName).absolutePath();
loadWorldEditFile(fileName);
}
setCursor(Qt::ArrowCursor);
}
void WorldEditorWindow::loadWorldEditFile(const QString &fileName)
{
Utils::WorldEditList worldEditList;
if (!Utils::loadWorldEditFile(fileName.toStdString(), worldEditList))
{
return;
}
m_undoStack->beginMacro(QString("Load %1").arg(fileName));
checkCurrentWorld();
m_undoStack->push(new CreateWorldCommand(fileName, m_primitivesModel));
for (size_t i = 0; i < worldEditList.size(); ++i)
{
switch (worldEditList[i].first)
{
case Utils::DataDirectoryType:
m_zoneBuilderBase->init(QString(worldEditList[i].second.c_str()), true);
break;
case Utils::ContextType:
break;
case Utils::LandscapeType:
m_undoStack->push(new LoadLandscapeCommand(QString(worldEditList[i].second.c_str()), m_primitivesModel, m_zoneBuilderBase));
break;
case Utils::PrimitiveType:
m_undoStack->push(new LoadRootPrimitiveCommand(QString(worldEditList[i].second.c_str()), m_primitivesModel));
break;
};
}
m_undoStack->endMacro();
}
void WorldEditorWindow::checkCurrentWorld()
{
}
void WorldEditorWindow::newWorldEditFile()
{
checkCurrentWorld();
m_undoStack->push(new CreateWorldCommand("NewWorldEdit", m_primitivesModel));
}
void WorldEditorWindow::saveWorldEditFile()
{
}
void WorldEditorWindow::openProjectSettings()
{
/*
LandscapeEditor::ProjectSettingsDialog *dialog = new LandscapeEditor::ProjectSettingsDialog("", this);
dialog->show();
int ok = dialog->exec();
if (ok == QDialog::Accepted)
{
}
delete dialog;
*/
}
void WorldEditorWindow::createMenus()
{
Core::IMenuManager *menuManager = Core::ICore::instance()->menuManager();
}
void WorldEditorWindow::createToolBars()
{
Core::IMenuManager *menuManager = Core::ICore::instance()->menuManager();
//QAction *action = menuManager->action(Core::Constants::NEW);
//m_ui.fileToolBar->addAction(action);
m_ui.fileToolBar->addAction(m_ui.newWorldEditAction);
QAction *action = menuManager->action(Core::Constants::OPEN);
m_ui.fileToolBar->addAction(action);
m_ui.fileToolBar->addAction(m_ui.saveWorldEditAction);
m_ui.fileToolBar->addSeparator();
action = menuManager->action(Core::Constants::UNDO);
if (action != 0)
m_ui.fileToolBar->addAction(action);
action = menuManager->action(Core::Constants::REDO);
if (action != 0)
m_ui.fileToolBar->addAction(action);
//action = menuManager->action(Core::Constants::SAVE);
//m_ui.fileToolBar->addAction(action);
//action = menuManager->action(Core::Constants::SAVE_AS);
//m_ui.fileToolBar->addAction(action);
}
void WorldEditorWindow::readSettings()
{
QSettings *settings = Core::ICore::instance()->settings();
settings->beginGroup(Constants::WORLD_EDITOR_SECTION);
restoreState(settings->value(Constants::WORLD_WINDOW_STATE).toByteArray());
restoreGeometry(settings->value(Constants::WORLD_WINDOW_GEOMETRY).toByteArray());
settings->endGroup();
}
void WorldEditorWindow::writeSettings()
{
QSettings *settings = Core::ICore::instance()->settings();
settings->beginGroup(Constants::WORLD_EDITOR_SECTION);
settings->setValue(Constants::WORLD_WINDOW_STATE, saveState());
settings->setValue(Constants::WORLD_WINDOW_GEOMETRY, saveGeometry());
settings->endGroup();
settings->sync();
}
} /* namespace LandscapeEditor */

View file

@ -0,0 +1,75 @@
// 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 WORLD_EDITOR_WINDOW_H
#define WORLD_EDITOR_WINDOW_H
// Project includes
#include "ui_world_editor_window.h"
// Qt includes
#include <QtGui/QUndoStack>
namespace LandscapeEditor
{
class ZoneBuilderBase;
}
namespace WorldEditor
{
class PrimitivesTreeModel;
class WorldEditorScene;
class WorldEditorWindow: public QMainWindow
{
Q_OBJECT
public:
WorldEditorWindow(QWidget *parent = 0);
~WorldEditorWindow();
QUndoStack *undoStack() const;
Q_SIGNALS:
public Q_SLOTS:
void open();
private Q_SLOTS:
void newWorldEditFile();
void saveWorldEditFile();
void openProjectSettings();
private:
void createMenus();
void createToolBars();
void readSettings();
void writeSettings();
void loadWorldEditFile(const QString &fileName);
void checkCurrentWorld();
QString m_lastDir;
PrimitivesTreeModel *m_primitivesModel;
QUndoStack *m_undoStack;
WorldEditorScene *m_worldEditorScene;
LandscapeEditor::ZoneBuilderBase *m_zoneBuilderBase;
Ui::WorldEditorWindow m_ui;
}; /* class WorldEditorWindow */
} /* namespace WorldEditor */
#endif // WORLD_EDITOR_WINDOW_H

View file

@ -0,0 +1,305 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>WorldEditorWindow</class>
<widget class="QMainWindow" name="WorldEditorWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<property name="windowIcon">
<iconset resource="world_editor.qrc">
<normaloff>:/icons/ic_nel_world_editor.png</normaloff>:/icons/ic_nel_world_editor.png</iconset>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="LandscapeEditor::LandscapeView" name="graphicsView">
<property name="dragMode">
<enum>QGraphicsView::RubberBandDrag</enum>
</property>
<property name="transformationAnchor">
<enum>QGraphicsView::AnchorUnderMouse</enum>
</property>
<property name="resizeAnchor">
<enum>QGraphicsView::AnchorUnderMouse</enum>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QToolBar" name="fileToolBar">
<property name="windowTitle">
<string>toolBar</string>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QToolBar" name="worldEditToolBar">
<property name="windowTitle">
<string>toolBar</string>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
<addaction name="selectAction"/>
<addaction name="moveAction"/>
<addaction name="rotateAction"/>
<addaction name="scaleAction"/>
<addaction name="turnAction"/>
<addaction name="radiusAction"/>
<addaction name="separator"/>
<addaction name="pointsAction"/>
</widget>
<widget class="QDockWidget" name="treePrimitivesDockWidget">
<property name="windowTitle">
<string>Primitives</string>
</property>
<attribute name="dockWidgetArea">
<number>2</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents">
<layout class="QGridLayout" name="gridLayout_2">
<property name="margin">
<number>3</number>
</property>
<property name="spacing">
<number>3</number>
</property>
<item row="0" column="0">
<widget class="WorldEditor::PrimitivesView" name="treePrimitivesView">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
<property name="animated">
<bool>true</bool>
</property>
<attribute name="headerCascadingSectionResizes">
<bool>true</bool>
</attribute>
<attribute name="headerDefaultSectionSize">
<number>250</number>
</attribute>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QToolBar" name="shToolBar">
<property name="windowTitle">
<string>toolBar</string>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
<addaction name="visibleLandAction"/>
<addaction name="visiblePrimitivesAction"/>
<addaction name="visibleLayersAction"/>
<addaction name="visibleDetailsAction"/>
<addaction name="visibleGridAction"/>
<addaction name="visibleGridPointsAction"/>
</widget>
<action name="loadPrimitiveAction">
<property name="text">
<string>loadPrimitive</string>
</property>
</action>
<action name="newPrimitiveAction">
<property name="text">
<string>newPrimitive</string>
</property>
</action>
<action name="loadLandAction">
<property name="icon">
<iconset resource="../landscape_editor/landscape_editor.qrc">
<normaloff>:/icons/ic_nel_zonel.png</normaloff>:/icons/ic_nel_zonel.png</iconset>
</property>
<property name="text">
<string>loadLand</string>
</property>
</action>
<action name="landSettingsAction">
<property name="icon">
<iconset resource="../landscape_editor/landscape_editor.qrc">
<normaloff>:/icons/ic_nel_landscape_settings.png</normaloff>:/icons/ic_nel_landscape_settings.png</iconset>
</property>
<property name="text">
<string>LandSettings</string>
</property>
</action>
<action name="visibleLandAction">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>S/H Land</string>
</property>
</action>
<action name="visiblePrimitivesAction">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>S/H Primitives</string>
</property>
</action>
<action name="visibleLayersAction">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>S/H Layers</string>
</property>
</action>
<action name="visibleDetailsAction">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>S/H Details</string>
</property>
</action>
<action name="visibleGridAction">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="../landscape_editor/landscape_editor.qrc">
<normaloff>:/icons/ic_grid.png</normaloff>:/icons/ic_grid.png</iconset>
</property>
<property name="text">
<string>S/H Grid</string>
</property>
</action>
<action name="visibleGridPointsAction">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>S/H Grid points</string>
</property>
</action>
<action name="newWorldEditAction">
<property name="text">
<string>New World Edit file</string>
</property>
</action>
<action name="saveWorldEditAction">
<property name="text">
<string>Save World Edit file</string>
</property>
</action>
<action name="selectAction">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="world_editor.qrc">
<normaloff>:/icons/ic_nel_select.png</normaloff>:/icons/ic_nel_select.png</iconset>
</property>
<property name="text">
<string>Select</string>
</property>
</action>
<action name="moveAction">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="world_editor.qrc">
<normaloff>:/icons/ic_nel_move.png</normaloff>:/icons/ic_nel_move.png</iconset>
</property>
<property name="text">
<string>Move</string>
</property>
</action>
<action name="rotateAction">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="world_editor.qrc">
<normaloff>:/icons/ic_nel_rotate.png</normaloff>:/icons/ic_nel_rotate.png</iconset>
</property>
<property name="text">
<string>Rotate</string>
</property>
</action>
<action name="scaleAction">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="world_editor.qrc">
<normaloff>:/icons/ic_nel_scale.png</normaloff>:/icons/ic_nel_scale.png</iconset>
</property>
<property name="text">
<string>Scale</string>
</property>
</action>
<action name="turnAction">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="world_editor.qrc">
<normaloff>:/icons/ic_nel_turn.png</normaloff>:/icons/ic_nel_turn.png</iconset>
</property>
<property name="text">
<string>Turn</string>
</property>
</action>
<action name="radiusAction">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Radius</string>
</property>
</action>
<action name="pointsAction">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Edit points</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>
<class>LandscapeEditor::LandscapeView</class>
<extends>QGraphicsView</extends>
<header>../landscape_editor/landscape_view.h</header>
</customwidget>
<customwidget>
<class>WorldEditor::PrimitivesView</class>
<extends>QTreeView</extends>
<header>primitives_view.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="world_editor.qrc"/>
<include location="../landscape_editor/landscape_editor.qrc"/>
</resources>
<connections/>
</ui>