From 92e553802a258b2349f91ed33cdd57ca6eb03933 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Thu, 2 Jun 2011 16:57:10 +0300 Subject: [PATCH 01/89] Added: #1301 Added pixmap database --HG-- branch : gsoc2011-worldeditorqt --- .../plugins/landscape_editor/CMakeLists.txt | 6 +- .../plugins/landscape_editor/builder_zone.cpp | 104 +++++++ .../plugins/landscape_editor/builder_zone.h | 75 +++++ .../landscape_editor/builder_zone_region.cpp | 28 ++ .../landscape_editor/builder_zone_region.h | 33 +++ .../landscape_editor_plugin.h | 2 +- .../landscape_editor_window.cpp | 7 +- .../landscape_editor_window.h | 2 + .../landscape_editor_window.ui | 17 ++ .../landscape_editor/landscape_scene.cpp | 38 +++ .../landscape_editor/landscape_scene.h | 42 +++ .../landscape_editor/zone_list_model.cpp | 165 +++++++++++ .../landscape_editor/zone_list_model.h | 82 ++++++ .../landscape_editor/zone_list_widget.cpp | 44 +++ .../landscape_editor/zone_list_widget.h | 54 ++++ .../landscape_editor/zone_list_widget.ui | 266 ++++++++++++++++++ 16 files changed, 962 insertions(+), 3 deletions(-) create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.cpp create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.h create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_model.cpp create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_model.h create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_widget.cpp create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_widget.h create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_widget.ui diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt index 3b6a61c5e..2f7487fe7 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt @@ -11,9 +11,13 @@ 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.h + zone_list_model.h + zone_list_widget.h ) SET(OVQT_PLUGIN_LANDSCAPE_EDITOR_UIS landscape_editor_window.ui + zone_list_widget.ui ) SET(OVQT_PLUGIN_LANDSCAPE_EDITOR_RCS landscape_editor.qrc) @@ -37,7 +41,7 @@ ADD_LIBRARY(ovqt_plugin_landscape_editor MODULE ${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) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp new file mode 100644 index 000000000..d79770cf3 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp @@ -0,0 +1,104 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +// Project includes +#include "builder_zone.h" +#include "zone_list_model.h" + +// NeL includes +#include + +// Qt includes +#include +#include + +namespace LandscapeEditor +{ + +ZoneBuilder::ZoneBuilder() + : m_zoneListModel(0) +{ + m_zoneListModel = new ZoneListModel(); + m_lastPathName = ""; +} + +ZoneBuilder::~ZoneBuilder() +{ + delete m_zoneListModel; +} + +bool ZoneBuilder::init(const QString &pathName, bool makeAZone) +{ + bool bRet = true; + 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_zoneListModel->resetModel(); + if (!m_zoneListModel->rebuildModel(zoneBitmapPath, m_zoneBank)) + { + m_zoneBank.reset(); + return false; + } + } + + if ((makeAZone) && (bRet)) + newZone(); + return bRet; +} + +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); + } + return true; +} + +ZoneListModel *ZoneBuilder::zoneModel() const +{ + return m_zoneListModel; +} + +void ZoneBuilder::newZone (bool bDisplay) +{ +} + +} /* namespace LandscapeEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h new file mode 100644 index 000000000..b578a2bb2 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h @@ -0,0 +1,75 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +#ifndef BUILDER_ZONE_H +#define BUILDER_ZONE_H + +// Project includes + +// NeL includes +#include + +// STL includes +#include +#include + +// Qt includes +#include + +namespace LandscapeEditor +{ +class ZoneListModel; + +/** +@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 +ZoneListModel contains the graphics for the zones +*/ +class ZoneBuilder +{ +public: + ZoneBuilder(); + ~ZoneBuilder(); + + // Init zoneBank and init zone pixmap database + bool init(const QString &pathName, bool bMakeAZone); + + void newZone(bool bDisplay=true); + + // Accessors + NLLIGO::CZoneBank &getZoneBank() + { + return m_zoneBank; + } + ZoneListModel *zoneModel() const; +private: + + // Scan ./zoneligos dir and add all *.ligozone files to zoneBank + bool initZoneBank (const QString &path); + + sint32 m_minX, m_maxX, m_minY, m_maxY; + QString m_lastPathName; + + ZoneListModel *m_zoneListModel; + NLLIGO::CZoneBank m_zoneBank; + std::vector m_currentSelection; +}; + +} /* namespace LandscapeEditor */ + +#endif // BUILDER_ZONE_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.cpp new file mode 100644 index 000000000..4dbd3e9e1 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.cpp @@ -0,0 +1,28 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +// Project includes +#include "builder_zone_region.h" + +// NeL includes +#include + +// Qt includes + +namespace LandscapeEditor +{ +} /* namespace LandscapeEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.h new file mode 100644 index 000000000..158c72715 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.h @@ -0,0 +1,33 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +#ifndef BUILDER_ZONE_REGION_H +#define BUILDER_ZONE_REGION_H + +// Project includes + +// NeL includes +#include + +// Qt includes + +namespace LandscapeEditor +{ + +} /* namespace LandscapeEditor */ + +#endif // BUILDER_ZONE_REGION_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_plugin.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_plugin.h index 67a3172ee..8f9f811cf 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_plugin.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_plugin.h @@ -91,7 +91,7 @@ public: } virtual QIcon icon() const { - return QIcon(); + return QIcon(Constants::ICON_LANDSCAPE_ITEM); } virtual void open(); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp index 4b075adfc..c46278f38 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp @@ -18,6 +18,7 @@ // Project includes #include "landscape_editor_window.h" #include "landscape_editor_constants.h" +#include "zone_list_model.h" #include "../core/icore.h" #include "../core/imenu_manager.h" @@ -40,7 +41,11 @@ LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent) m_ui.setupUi(this); m_undoStack = new QUndoStack(this); - + /* + m_zoneBuilder = new ZoneBuilder(); + m_zoneBuilder->init("e:/-nel-/install/continents/newbieland", false); + m_ui.zoneListWidget->setModel(m_zoneBuilder->zoneModel()); + */ createMenus(); readSettings(); } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h index cc17e6cbc..61e0c7eb1 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h @@ -20,6 +20,7 @@ // Project includes #include "ui_landscape_editor_window.h" +#include "builder_zone.h" // Qt includes #include @@ -47,6 +48,7 @@ private: void readSettings(); void writeSettings(); + ZoneBuilder *m_zoneBuilder; QUndoStack *m_undoStack; Ui::LandscapeEditorWindow m_ui; }; /* class LandscapeEditorWindow */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui index 5d9606ddf..ce6e905a3 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui @@ -35,7 +35,24 @@ false + + + Zones + + + 2 + + + + + + LandscapeEditor::ZoneListWidget + QWidget +
zone_list_widget.h
+ 1 +
+
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp new file mode 100644 index 000000000..f491dfa2b --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp @@ -0,0 +1,38 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +// Project includes +#include "landscape_scene.h" + +// NeL includes +#include + +// Qt includes + +namespace LandscapeEditor +{ + +LandscapeScene::LandscapeScene(QObject *parent) + : QGraphicsScene(parent) +{ +} + +LandscapeScene::~LandscapeScene() +{ +} + +} /* namespace LandscapeEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h new file mode 100644 index 000000000..d4fb91c78 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h @@ -0,0 +1,42 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +#ifndef LANDSCAPE_SCENE_H +#define LANDSCAPE_SCENE_H + +// Project includes + +// NeL includes + +// Qt includes +#include + +namespace LandscapeEditor +{ + +class LandscapeScene : public QGraphicsScene +{ + Q_OBJECT + +public: + LandscapeScene(QObject *parent = 0); + virtual ~LandscapeScene(); +}; + +} /* namespace LandscapeEditor */ + +#endif // LANDSCAPE_SCENE_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_model.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_model.cpp new file mode 100644 index 000000000..32dded570 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_model.cpp @@ -0,0 +1,165 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +// Project includes +#include "zone_list_model.h" + +// NeL includes +#include + +// STL includes +#include +#include + +// Qt includes +#include +#include +#include + +namespace LandscapeEditor +{ + +ZoneListModel::ZoneListModel(int pixmapSize, QObject *parent) + : QAbstractListModel(parent), + m_pixmapSize(pixmapSize) +{ + +} +ZoneListModel::~ZoneListModel() +{ + resetModel(); +} + +int ZoneListModel::rowCount(const QModelIndex & /* parent */) const +{ + return m_pixmapMap.count(); +} + +int ZoneListModel::columnCount(const QModelIndex & /* parent */) const +{ + return 1; +} + +QVariant ZoneListModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + if (role == Qt::TextAlignmentRole) + { + return int(Qt::AlignLeft | Qt::AlignVCenter); + } + else if (role == Qt::DisplayRole) + { + return m_pixmapNameList.at(index.row()); + } + else if (role == Qt::DecorationRole) + { + QPixmap *pixmap = getSmallPixmap(m_pixmapNameList.at(index.row())); + return qVariantFromValue(*pixmap); + } + return QVariant(); +} + +QVariant ZoneListModel::headerData(int section, + Qt::Orientation /* orientation */, + int role) const +{ + if (role != Qt::DisplayRole) + return QVariant(); + return QVariant(); +} + +void ZoneListModel::setSmallPixmapSize(int pixmapSize) +{ + m_pixmapSize = pixmapSize; +} + +void ZoneListModel::resetModel() +{ + beginResetModel(); + Q_FOREACH(QString name, m_pixmapNameList) + { + QPixmap *pixmap = m_pixmapMap.value(name); + delete pixmap; + QPixmap *smallPixmap = m_smallPixmapMap.value(name); + delete smallPixmap; + } + m_pixmapMap.clear(); + m_pixmapNameList.clear(); + m_smallPixmapMap.clear(); + endResetModel(); +} + +bool ZoneListModel::rebuildModel(const QString &zonePath, NLLIGO::CZoneBank &zoneBank) +{ + beginResetModel(); + m_zonePath = zonePath; + + QProgressDialog *progressDialog = new QProgressDialog(); + + std::vector zoneNames; + zoneBank.getCategoryValues ("zone", zoneNames); + progressDialog->setRange(0, zoneNames.size()); + for (uint i = 0; i < zoneNames.size(); ++i) + { + QApplication::processEvents(); + progressDialog->setValue(i); + + NLLIGO::CZoneBankElement *zoneBankItem = zoneBank.getElementByZoneName (zoneNames[i]); + + // Read the texture file + QString zonePixmapName(zoneNames[i].c_str()); + uint8 sizeX = zoneBankItem->getSizeX(); + uint8 sizeY = zoneBankItem->getSizeY(); + const std::vector &rMask = zoneBankItem->getMask(); + + QPixmap *pixmap = new QPixmap(zonePath + zonePixmapName + ".png"); + QPixmap *smallPixmap = new QPixmap(pixmap->scaled(m_pixmapSize * sizeX, m_pixmapSize * sizeY)); + + m_pixmapMap.insert(zonePixmapName, pixmap); + m_smallPixmapMap.insert(zonePixmapName, smallPixmap); + + } + m_pixmapNameList = m_pixmapMap.keys(); + endResetModel(); + delete progressDialog; + return false; +} + +QPixmap *ZoneListModel::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; +} + +QPixmap *ZoneListModel::getSmallPixmap(const QString &zoneName) const +{ + QPixmap *result = 0; + if (!m_pixmapMap.contains(zoneName)) + nlwarning("QPixmap %s not found", zoneName.toStdString().c_str()); + else + result = m_smallPixmapMap.value(zoneName); + return result; +} + + +} /* namespace LandscapeEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_model.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_model.h new file mode 100644 index 000000000..1bfb0f93f --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_model.h @@ -0,0 +1,82 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +#ifndef ZONE_LIST_MODEL_H +#define ZONE_LIST_MODEL_H + +// Project includes + +// NeL includes +#include + +// Qt includes +#include +#include +#include +#include + +namespace LandscapeEditor +{ + +/** +@class ZoneListModel +@brief ZoneListModel contains the image database for QGraphicsScene and +small images for QListView +@details +*/ +class ZoneListModel : public QAbstractListModel +{ + Q_OBJECT +public: + ZoneListModel(int pixmapSize = 64, QObject *parent = 0); + ~ZoneListModel(); + + 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 setSmallPixmapSize(int pixmapSize); + + /// Unload all images and reset model + void resetModel(); + + /// Load all images(png) from zonePath, list images gets from zoneBank + bool rebuildModel(const QString &zonePath, NLLIGO::CZoneBank &zoneBank); + + /// Get original pixmap + /// @return QPixmap* if the image is in the database ; otherwise returns 0. + QPixmap *getPixmap(const QString &zoneName) const; + + /// Get scaled pixmap (pixmapSize * zoneSize.sizeX, pixmapSize * zoneSize.sizeY) + /// @return QPixmap* if the image is in the database ; otherwise returns 0. + QPixmap *getSmallPixmap(const QString &zoneName) const; +private: + + QString m_zonePath; + int m_pixmapSize; + QMap m_pixmapMap; + QMap m_smallPixmapMap; + QList m_pixmapNameList; +}; + +} /* namespace LandscapeEditor */ + +#endif // ZONE_LIST_MODEL_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_widget.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_widget.cpp new file mode 100644 index 000000000..423c2c50f --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_widget.cpp @@ -0,0 +1,44 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +// Project includes +#include "zone_list_widget.h" + +// NeL includes +#include + +// Qt includes + +namespace LandscapeEditor +{ + +ZoneListWidget::ZoneListWidget(QWidget *parent) + : QWidget(parent) +{ + m_ui.setupUi(this); +} + +ZoneListWidget::~ZoneListWidget() +{ +} + +void ZoneListWidget::setModel(QAbstractItemModel *model) +{ + m_ui.listView->setModel(model); +} + +} /* namespace LandscapeEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_widget.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_widget.h new file mode 100644 index 000000000..5b90f81d6 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_widget.h @@ -0,0 +1,54 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +#ifndef ZONE_LIST_WIDGET_H +#define ZONE_LIST_WIDGET_H + +// Project includes +#include "ui_zone_list_widget.h" + +// NeL includes + +// Qt includes + +namespace LandscapeEditor +{ +/** +@class ZoneListWidget +@brief ZoneListWidget +@details +*/ +class ZoneListWidget: public QWidget +{ + Q_OBJECT + +public: + ZoneListWidget(QWidget *parent = 0); + ~ZoneListWidget(); + + void setModel(QAbstractItemModel *model); + +Q_SIGNALS: +public Q_SLOTS: +private Q_SLOTS: +private: + Ui::ZoneListWidget m_ui; +}; /* ZoneListWidget */ + +} /* namespace LandscapeEditor */ + +#endif // ZONE_LIST_WIDGET_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_widget.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_widget.ui new file mode 100644 index 000000000..725e6cf83 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_widget.ui @@ -0,0 +1,266 @@ + + + ZoneListWidget + + + + 0 + 0 + 359 + 579 + + + + Form + + + + 3 + + + 3 + + + + + Filter + + + + 6 + + + 3 + + + + + + <Unused> + + + + + + + + + + + + Random + + + + + Fyll cycle + + + + + + + + true + + + + <Unused> + + + + + + + + true + + + + + + + true + + + + And + + + + + Or + + + + + + + + false + + + + <Unused> + + + + + + + + false + + + + + + + false + + + + And + + + + + Or + + + + + + + + false + + + + <Unused> + + + + + + + + false + + + + + + + false + + + + And + + + + + Or + + + + + + + + + + + Placement + + + + 6 + + + 3 + + + + + + 0° + + + + + 90° + + + + + 180° + + + + + 170° + + + + + Random + + + + + Full cycle + + + + + + + + + NoFlip + + + + + Flip + + + + + Random + + + + + Fyll cycle + + + + + + + + Force + + + + + + + Not propogate + + + + + + + + + + + + + + From f6bcb791ec94e5c50de4aad9737be3dbc643e557 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Thu, 2 Jun 2011 23:31:21 +0300 Subject: [PATCH 02/89] Added: #1301 Added filter for list zones in landscape editor. --HG-- branch : gsoc2011-worldeditorqt --- .../plugins/landscape_editor/CMakeLists.txt | 7 +- .../plugins/landscape_editor/builder_zone.cpp | 7 +- .../plugins/landscape_editor/builder_zone.h | 6 +- ..._list_widget.cpp => landscape_actions.cpp} | 18 +- ...zone_list_widget.h => landscape_actions.h} | 28 +- .../landscape_editor_window.cpp | 12 +- .../landscape_editor_window.ui | 6 +- ...ne_list_model.cpp => list_zones_model.cpp} | 46 +- .../{zone_list_model.h => list_zones_model.h} | 18 +- .../landscape_editor/list_zones_widget.cpp | 219 ++++++++ .../landscape_editor/list_zones_widget.h | 68 +++ .../landscape_editor/list_zones_widget.ui | 478 ++++++++++++++++++ .../landscape_editor/zone_list_widget.ui | 266 ---------- 13 files changed, 827 insertions(+), 352 deletions(-) rename code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/{zone_list_widget.cpp => landscape_actions.cpp} (76%) rename code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/{zone_list_widget.h => landscape_actions.h} (68%) rename code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/{zone_list_model.cpp => list_zones_model.cpp} (73%) rename code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/{zone_list_model.h => list_zones_model.h} (86%) create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.ui delete mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_widget.ui diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt index 2f7487fe7..714d1f125 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt @@ -12,12 +12,13 @@ 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.h - zone_list_model.h - zone_list_widget.h + list_zones_model.h + list_zones_widget.h + landscape_actions.h ) SET(OVQT_PLUGIN_LANDSCAPE_EDITOR_UIS landscape_editor_window.ui - zone_list_widget.ui + list_zones_widget.ui ) SET(OVQT_PLUGIN_LANDSCAPE_EDITOR_RCS landscape_editor.qrc) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp index d79770cf3..42242921e 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp @@ -17,7 +17,7 @@ // Project includes #include "builder_zone.h" -#include "zone_list_model.h" +#include "list_zones_model.h" // NeL includes #include @@ -32,7 +32,7 @@ namespace LandscapeEditor ZoneBuilder::ZoneBuilder() : m_zoneListModel(0) { - m_zoneListModel = new ZoneListModel(); + m_zoneListModel = new ListZonesModel(); m_lastPathName = ""; } @@ -67,7 +67,6 @@ bool ZoneBuilder::init(const QString &pathName, bool makeAZone) return false; } } - if ((makeAZone) && (bRet)) newZone(); return bRet; @@ -92,7 +91,7 @@ bool ZoneBuilder::initZoneBank (const QString &pathName) return true; } -ZoneListModel *ZoneBuilder::zoneModel() const +ListZonesModel *ZoneBuilder::zoneModel() const { return m_zoneListModel; } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h index b578a2bb2..97c4d8d3a 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h @@ -32,7 +32,7 @@ namespace LandscapeEditor { -class ZoneListModel; +class ListZonesModel; /** @class ZoneBuilder @@ -56,7 +56,7 @@ public: { return m_zoneBank; } - ZoneListModel *zoneModel() const; + ListZonesModel *zoneModel() const; private: // Scan ./zoneligos dir and add all *.ligozone files to zoneBank @@ -65,7 +65,7 @@ private: sint32 m_minX, m_maxX, m_minY, m_maxY; QString m_lastPathName; - ZoneListModel *m_zoneListModel; + ListZonesModel *m_zoneListModel; NLLIGO::CZoneBank m_zoneBank; std::vector m_currentSelection; }; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_widget.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp similarity index 76% rename from code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_widget.cpp rename to code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp index 423c2c50f..f0b86dd8e 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_widget.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp @@ -16,7 +16,7 @@ // along with this program. If not, see . // Project includes -#include "zone_list_widget.h" +#include "landscape_actions.h" // NeL includes #include @@ -25,20 +25,4 @@ namespace LandscapeEditor { - -ZoneListWidget::ZoneListWidget(QWidget *parent) - : QWidget(parent) -{ - m_ui.setupUi(this); -} - -ZoneListWidget::~ZoneListWidget() -{ -} - -void ZoneListWidget::setModel(QAbstractItemModel *model) -{ - m_ui.listView->setModel(model); -} - } /* namespace LandscapeEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_widget.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h similarity index 68% rename from code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_widget.h rename to code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h index 5b90f81d6..fdcda5451 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_widget.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h @@ -15,11 +15,10 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -#ifndef ZONE_LIST_WIDGET_H -#define ZONE_LIST_WIDGET_H +#ifndef LANDSCAPE_ACTIONS_H +#define LANDSCAPE_ACTIONS_H // Project includes -#include "ui_zone_list_widget.h" // NeL includes @@ -27,28 +26,7 @@ namespace LandscapeEditor { -/** -@class ZoneListWidget -@brief ZoneListWidget -@details -*/ -class ZoneListWidget: public QWidget -{ - Q_OBJECT - -public: - ZoneListWidget(QWidget *parent = 0); - ~ZoneListWidget(); - - void setModel(QAbstractItemModel *model); - -Q_SIGNALS: -public Q_SLOTS: -private Q_SLOTS: -private: - Ui::ZoneListWidget m_ui; -}; /* ZoneListWidget */ } /* namespace LandscapeEditor */ -#endif // ZONE_LIST_WIDGET_H +#endif // LANDSCAPE_ACTIONS_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp index c46278f38..eb9b8b8e8 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp @@ -18,7 +18,7 @@ // Project includes #include "landscape_editor_window.h" #include "landscape_editor_constants.h" -#include "zone_list_model.h" +#include "list_zones_model.h" #include "../core/icore.h" #include "../core/imenu_manager.h" @@ -41,11 +41,11 @@ LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent) m_ui.setupUi(this); m_undoStack = new QUndoStack(this); - /* - m_zoneBuilder = new ZoneBuilder(); - m_zoneBuilder->init("e:/-nel-/install/continents/newbieland", false); - m_ui.zoneListWidget->setModel(m_zoneBuilder->zoneModel()); - */ + m_zoneBuilder = new ZoneBuilder(); + m_zoneBuilder->init("e:/-nel-/install/continents/newbieland", false); + m_ui.zoneListWidget->setModel(m_zoneBuilder->zoneModel()); + m_ui.zoneListWidget->setZoneBuilder(m_zoneBuilder); + m_ui.zoneListWidget->updateUi(); createMenus(); readSettings(); } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui index ce6e905a3..ac16ad9fd 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui @@ -42,14 +42,14 @@ 2 - + - LandscapeEditor::ZoneListWidget + LandscapeEditor::ListZonesWidget QWidget -
zone_list_widget.h
+
list_zones_widget.h
1
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_model.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_model.cpp similarity index 73% rename from code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_model.cpp rename to code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_model.cpp index 32dded570..ffcb7617b 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_model.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_model.cpp @@ -16,7 +16,7 @@ // along with this program. If not, see . // Project includes -#include "zone_list_model.h" +#include "list_zones_model.h" // NeL includes #include @@ -33,28 +33,28 @@ namespace LandscapeEditor { -ZoneListModel::ZoneListModel(int pixmapSize, QObject *parent) +ListZonesModel::ListZonesModel(int pixmapSize, QObject *parent) : QAbstractListModel(parent), m_pixmapSize(pixmapSize) { } -ZoneListModel::~ZoneListModel() +ListZonesModel::~ListZonesModel() { resetModel(); } -int ZoneListModel::rowCount(const QModelIndex & /* parent */) const +int ListZonesModel::rowCount(const QModelIndex & /* parent */) const { - return m_pixmapMap.count(); + return m_pixmapNameList.count(); } -int ZoneListModel::columnCount(const QModelIndex & /* parent */) const +int ListZonesModel::columnCount(const QModelIndex & /* parent */) const { return 1; } -QVariant ZoneListModel::data(const QModelIndex &index, int role) const +QVariant ListZonesModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) return QVariant(); @@ -75,21 +75,29 @@ QVariant ZoneListModel::data(const QModelIndex &index, int role) const return QVariant(); } -QVariant ZoneListModel::headerData(int section, - Qt::Orientation /* orientation */, - int role) const +QVariant ListZonesModel::headerData(int section, + Qt::Orientation /* orientation */, + int role) const { if (role != Qt::DisplayRole) return QVariant(); return QVariant(); } -void ZoneListModel::setSmallPixmapSize(int pixmapSize) +void ListZonesModel::setSmallPixmapSize(int pixmapSize) { m_pixmapSize = pixmapSize; } -void ZoneListModel::resetModel() +void ListZonesModel::setListZones(QStringList &listZones) +{ + beginResetModel(); + m_pixmapNameList.clear(); + m_pixmapNameList = listZones; + endResetModel(); +} + +void ListZonesModel::resetModel() { beginResetModel(); Q_FOREACH(QString name, m_pixmapNameList) @@ -105,12 +113,13 @@ void ZoneListModel::resetModel() endResetModel(); } -bool ZoneListModel::rebuildModel(const QString &zonePath, NLLIGO::CZoneBank &zoneBank) +bool ListZonesModel::rebuildModel(const QString &zonePath, NLLIGO::CZoneBank &zoneBank) { beginResetModel(); m_zonePath = zonePath; QProgressDialog *progressDialog = new QProgressDialog(); + progressDialog->show(); std::vector zoneNames; zoneBank.getCategoryValues ("zone", zoneNames); @@ -129,19 +138,22 @@ bool ZoneListModel::rebuildModel(const QString &zonePath, NLLIGO::CZoneBank &zon const std::vector &rMask = zoneBankItem->getMask(); QPixmap *pixmap = new QPixmap(zonePath + zonePixmapName + ".png"); + if (pixmap->isNull()) + { + // Generate filled pixmap + } QPixmap *smallPixmap = new QPixmap(pixmap->scaled(m_pixmapSize * sizeX, m_pixmapSize * sizeY)); m_pixmapMap.insert(zonePixmapName, pixmap); m_smallPixmapMap.insert(zonePixmapName, smallPixmap); } - m_pixmapNameList = m_pixmapMap.keys(); endResetModel(); delete progressDialog; - return false; + return true; } -QPixmap *ZoneListModel::getPixmap(const QString &zoneName) const +QPixmap *ListZonesModel::getPixmap(const QString &zoneName) const { QPixmap *result = 0; if (!m_pixmapMap.contains(zoneName)) @@ -151,7 +163,7 @@ QPixmap *ZoneListModel::getPixmap(const QString &zoneName) const return result; } -QPixmap *ZoneListModel::getSmallPixmap(const QString &zoneName) const +QPixmap *ListZonesModel::getSmallPixmap(const QString &zoneName) const { QPixmap *result = 0; if (!m_pixmapMap.contains(zoneName)) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_model.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_model.h similarity index 86% rename from code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_model.h rename to code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_model.h index 1bfb0f93f..16a28bf07 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_model.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_model.h @@ -15,8 +15,8 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -#ifndef ZONE_LIST_MODEL_H -#define ZONE_LIST_MODEL_H +#ifndef LIST_ZONES_MODEL_H +#define LIST_ZONES_MODEL_H // Project includes @@ -33,17 +33,17 @@ namespace LandscapeEditor { /** -@class ZoneListModel -@brief ZoneListModel contains the image database for QGraphicsScene and +@class ListZonesModel +@brief ListZonesModel contains the image database for QGraphicsScene and small images for QListView @details */ -class ZoneListModel : public QAbstractListModel +class ListZonesModel : public QAbstractListModel { Q_OBJECT public: - ZoneListModel(int pixmapSize = 64, QObject *parent = 0); - ~ZoneListModel(); + ListZonesModel(int pixmapSize = 64, QObject *parent = 0); + ~ListZonesModel(); int rowCount(const QModelIndex &parent) const; int columnCount(const QModelIndex &parent) const; @@ -58,6 +58,8 @@ public: /// Unload all images and reset model void resetModel(); + void setListZones(QStringList &listZones); + /// Load all images(png) from zonePath, list images gets from zoneBank bool rebuildModel(const QString &zonePath, NLLIGO::CZoneBank &zoneBank); @@ -79,4 +81,4 @@ private: } /* namespace LandscapeEditor */ -#endif // ZONE_LIST_MODEL_H +#endif // LIST_ZONES_MODEL_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp new file mode 100644 index 000000000..8dcb87383 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp @@ -0,0 +1,219 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +// Project includes +#include "list_zones_widget.h" +#include "builder_zone.h" +#include "list_zones_model.h" + +// NeL includes +#include +#include +#include + +// STL includes +#include +#include + +// Qt includes +#include + +namespace LandscapeEditor +{ + +ListZonesWidget::ListZonesWidget(QWidget *parent) + : QWidget(parent), + m_zoneBuilder(0) +{ + m_ui.setupUi(this); + + 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 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.categoryTypeComboBox_1->addItems(listCategories); + m_ui.categoryTypeComboBox_2->addItems(listCategories); + m_ui.categoryTypeComboBox_3->addItems(listCategories); + m_ui.categoryTypeComboBox_4->addItems(listCategories); + + disableSignals(false); +} + +void ListZonesWidget::setModel(QAbstractItemModel *model) +{ + m_ui.listView->setModel(model); +} + +void ListZonesWidget::setZoneBuilder(ZoneBuilder *zoneBuilder) +{ + m_zoneBuilder = zoneBuilder; +} + +void ListZonesWidget::updateFilters_1(const QString &value) +{ + disableSignals(true); + std::vector 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 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 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 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 currentSelection; + zoneBank.getSelection (currentSelection); + + QStringList listSelection; + for (size_t i = 0; i < currentSelection.size(); ++i) + listSelection << currentSelection[i]->getName().c_str(); + m_zoneBuilder->zoneModel()->setListZones(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 */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h new file mode 100644 index 000000000..fed0134cf --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h @@ -0,0 +1,68 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +#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 ZoneBuilder; + +/** +@class ZoneListWidget +@brief ZoneListWidget +@details +*/ +class ListZonesWidget: public QWidget +{ + Q_OBJECT + +public: + ListZonesWidget(QWidget *parent = 0); + ~ListZonesWidget(); + + void updateUi(); + void setZoneBuilder(ZoneBuilder *zoneBuilder); + void setModel(QAbstractItemModel *model); + +Q_SIGNALS: +public 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); + +private Q_SLOTS: + void updateListZones(); + +private: + void disableSignals(bool block); + + ZoneBuilder *m_zoneBuilder; + Ui::ListZonesWidget m_ui; +}; /* ZoneListWidget */ + +} /* namespace LandscapeEditor */ + +#endif // LIST_ZONES_WIDGET_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.ui new file mode 100644 index 000000000..585371cb7 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.ui @@ -0,0 +1,478 @@ + + + ListZonesWidget + + + + 0 + 0 + 359 + 579 + + + + Form + + + + 3 + + + 3 + + + + + Filter + + + + 6 + + + 3 + + + + + + + + + + + + Random + + + + + Fyll cycle + + + + + + + + true + + + + + + + true + + + + + + + true + + + + And + + + + + Or + + + + + + + + true + + + + + + + true + + + + + + + true + + + + And + + + + + Or + + + + + + + + true + + + + + + + true + + + + + + + true + + + + And + + + + + Or + + + + + + + + ... + + + + :/core/icons/ic_nel_add_item.png + :/core/icons/ic_nel_delete_item.png:/core/icons/ic_nel_add_item.png + + + true + + + true + + + + + + + ... + + + + :/core/icons/ic_nel_add_item.png + :/core/icons/ic_nel_delete_item.png:/core/icons/ic_nel_add_item.png + + + true + + + true + + + + + + + ... + + + + :/core/icons/ic_nel_add_item.png + :/core/icons/ic_nel_delete_item.png:/core/icons/ic_nel_add_item.png + + + true + + + true + + + + + + + + + + Placement + + + + 6 + + + 3 + + + + + + 0° + + + + + 90° + + + + + 180° + + + + + 170° + + + + + Random + + + + + Full cycle + + + + + + + + + NoFlip + + + + + Flip + + + + + Random + + + + + Fyll cycle + + + + + + + + Force + + + + + + + Not propogate + + + + + + + + + + + + + + + + + addFilterButton_1 + toggled(bool) + categoryTypeComboBox_2 + setVisible(bool) + + + 20 + 36 + + + 81 + 53 + + + + + addFilterButton_1 + toggled(bool) + categoryValueComboBox_2 + setVisible(bool) + + + 24 + 32 + + + 181 + 50 + + + + + addFilterButton_1 + toggled(bool) + logicComboBox_2 + setVisible(bool) + + + 20 + 31 + + + 301 + 55 + + + + + addFilterButton_2 + toggled(bool) + categoryTypeComboBox_3 + setVisible(bool) + + + 27 + 62 + + + 57 + 75 + + + + + addFilterButton_2 + toggled(bool) + categoryValueComboBox_3 + setVisible(bool) + + + 23 + 58 + + + 156 + 76 + + + + + addFilterButton_2 + toggled(bool) + logicComboBox_3 + setVisible(bool) + + + 23 + 53 + + + 255 + 77 + + + + + addFilterButton_3 + toggled(bool) + categoryTypeComboBox_4 + setVisible(bool) + + + 32 + 94 + + + 44 + 104 + + + + + addFilterButton_3 + toggled(bool) + categoryValueComboBox_4 + setVisible(bool) + + + 32 + 94 + + + 207 + 103 + + + + + addFilterButton_3 + toggled(bool) + logicComboBox_4 + setVisible(bool) + + + 21 + 81 + + + 278 + 104 + + + + + addFilterButton_2 + toggled(bool) + addFilterButton_3 + setVisible(bool) + + + 15 + 59 + + + 16 + 80 + + + + + addFilterButton_1 + toggled(bool) + addFilterButton_2 + setVisible(bool) + + + 13 + 35 + + + 17 + 60 + + + + + diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_widget.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_widget.ui deleted file mode 100644 index 725e6cf83..000000000 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_list_widget.ui +++ /dev/null @@ -1,266 +0,0 @@ - - - ZoneListWidget - - - - 0 - 0 - 359 - 579 - - - - Form - - - - 3 - - - 3 - - - - - Filter - - - - 6 - - - 3 - - - - - - <Unused> - - - - - - - - - - - - Random - - - - - Fyll cycle - - - - - - - - true - - - - <Unused> - - - - - - - - true - - - - - - - true - - - - And - - - - - Or - - - - - - - - false - - - - <Unused> - - - - - - - - false - - - - - - - false - - - - And - - - - - Or - - - - - - - - false - - - - <Unused> - - - - - - - - false - - - - - - - false - - - - And - - - - - Or - - - - - - - - - - - Placement - - - - 6 - - - 3 - - - - - - 0° - - - - - 90° - - - - - 180° - - - - - 170° - - - - - Random - - - - - Full cycle - - - - - - - - - NoFlip - - - - - Flip - - - - - Random - - - - - Fyll cycle - - - - - - - - Force - - - - - - - Not propogate - - - - - - - - - - - - - - From b25f78234b12b029eb9afd652fddc459559fb23c Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Sat, 4 Jun 2011 17:29:08 +0300 Subject: [PATCH 03/89] Changed: #1301 Added project settings dialog. --HG-- branch : gsoc2011-worldeditorqt --- .../plugins/landscape_editor/CMakeLists.txt | 2 + .../plugins/landscape_editor/builder_zone.cpp | 97 +++++++++++++++++-- .../plugins/landscape_editor/builder_zone.h | 43 +++++++- .../landscape_editor_window.cpp | 33 ++++++- .../landscape_editor_window.h | 3 + .../landscape_editor_window.ui | 23 ++++- .../landscape_editor/list_zones_model.cpp | 80 +++++---------- .../landscape_editor/list_zones_model.h | 27 +++--- .../landscape_editor/list_zones_widget.cpp | 16 ++- .../landscape_editor/list_zones_widget.h | 9 +- .../project_settings_dialog.cpp | 52 ++++++++++ .../project_settings_dialog.h | 46 +++++++++ .../project_settings_dialog.ui | 97 +++++++++++++++++++ 13 files changed, 429 insertions(+), 99 deletions(-) create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.cpp create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.h create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.ui diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt index 714d1f125..227210366 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt @@ -15,10 +15,12 @@ SET(OVQT_PLUGIN_LANDSCAPE_EDITOR_HDR landscape_editor_plugin.h list_zones_model.h list_zones_widget.h landscape_actions.h + project_settings_dialog.h ) SET(OVQT_PLUGIN_LANDSCAPE_EDITOR_UIS landscape_editor_window.ui list_zones_widget.ui + project_settings_dialog.ui ) SET(OVQT_PLUGIN_LANDSCAPE_EDITOR_RCS landscape_editor.qrc) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp index 42242921e..3db771224 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp @@ -17,7 +17,6 @@ // Project includes #include "builder_zone.h" -#include "list_zones_model.h" // NeL includes #include @@ -25,20 +24,97 @@ // Qt includes #include #include +#include +#include namespace LandscapeEditor { +const int PixmapScale = 256; + +PixmapDatabase::PixmapDatabase() +{ +} + +PixmapDatabase::~PixmapDatabase() +{ + reset(); +} + +bool PixmapDatabase::loadPixmaps(const QString &zonePath, NLLIGO::CZoneBank &zoneBank) +{ + QProgressDialog *progressDialog = new QProgressDialog(); + progressDialog->show(); + + std::vector listNames; + zoneBank.getCategoryValues ("zone", listNames); + progressDialog->setRange(0, listNames.size()); + for (uint i = 0; i < listNames.size(); ++i) + { + QApplication::processEvents(); + 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 + } + // All pixmaps must be have same size + if (pixmap->width() != sizeX * PixmapScale) + { + QPixmap *scaledPixmap = new QPixmap(pixmap->scaled(sizeX * PixmapScale, sizeY * PixmapScale)); + delete pixmap; + m_pixmapMap.insert(zonePixmapName, scaledPixmap); + } + else + m_pixmapMap.insert(zonePixmapName, pixmap); + } + 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 = 0; + if (!m_pixmapMap.contains(zoneName)) + nlwarning("QPixmap %s not found", zoneName.toStdString().c_str()); + else + result = m_pixmapMap.value(zoneName); + return result; +} ZoneBuilder::ZoneBuilder() - : m_zoneListModel(0) + : m_pixmapDatabase(0) { - m_zoneListModel = new ListZonesModel(); + m_pixmapDatabase = new PixmapDatabase(); m_lastPathName = ""; } ZoneBuilder::~ZoneBuilder() { - delete m_zoneListModel; + delete m_pixmapDatabase; } bool ZoneBuilder::init(const QString &pathName, bool makeAZone) @@ -60,8 +136,8 @@ bool ZoneBuilder::init(const QString &pathName, bool makeAZone) // Construct the DataBase from the ZoneBank QString zoneBitmapPath = pathName; zoneBitmapPath += "/zonebitmaps/"; - m_zoneListModel->resetModel(); - if (!m_zoneListModel->rebuildModel(zoneBitmapPath, m_zoneBank)) + m_pixmapDatabase->reset(); + if (!m_pixmapDatabase->loadPixmaps(zoneBitmapPath, m_zoneBank)) { m_zoneBank.reset(); return false; @@ -91,9 +167,14 @@ bool ZoneBuilder::initZoneBank (const QString &pathName) return true; } -ListZonesModel *ZoneBuilder::zoneModel() const +PixmapDatabase *ZoneBuilder::pixmapDatabase() const +{ + return m_pixmapDatabase; +} + +QString ZoneBuilder::dataPath() const { - return m_zoneListModel; + return m_lastPathName; } void ZoneBuilder::newZone (bool bDisplay) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h index 97c4d8d3a..f69c2f7fb 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h @@ -29,16 +29,47 @@ // Qt includes #include +#include +#include +#include namespace LandscapeEditor { -class ListZonesModel; + +/** +@class PixmapDatabase +@brief PixmapDatabase contains the image database +@details +*/ +class PixmapDatabase +{ +public: + PixmapDatabase(); + ~PixmapDatabase(); + + /// Load all images(png) from zonePath, list images gets from zoneBank + bool loadPixmaps(const QString &zonePath, NLLIGO::CZoneBank &zoneBank); + + /// 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; +private: + + QMap m_pixmapMap; +}; + /** @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 -ZoneListModel contains the graphics for the zones +PixmapDatabase contains the graphics for the zones */ class ZoneBuilder { @@ -56,7 +87,11 @@ public: { return m_zoneBank; } - ListZonesModel *zoneModel() const; + + PixmapDatabase *pixmapDatabase() const; + + QString dataPath() const; + private: // Scan ./zoneligos dir and add all *.ligozone files to zoneBank @@ -65,7 +100,7 @@ private: sint32 m_minX, m_maxX, m_minY, m_maxY; QString m_lastPathName; - ListZonesModel *m_zoneListModel; + PixmapDatabase *m_pixmapDatabase; NLLIGO::CZoneBank m_zoneBank; std::vector m_currentSelection; }; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp index eb9b8b8e8..1b8716326 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp @@ -18,7 +18,7 @@ // Project includes #include "landscape_editor_window.h" #include "landscape_editor_constants.h" -#include "list_zones_model.h" +#include "project_settings_dialog.h" #include "../core/icore.h" #include "../core/imenu_manager.h" @@ -43,15 +43,18 @@ LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent) m_undoStack = new QUndoStack(this); m_zoneBuilder = new ZoneBuilder(); m_zoneBuilder->init("e:/-nel-/install/continents/newbieland", false); - m_ui.zoneListWidget->setModel(m_zoneBuilder->zoneModel()); m_ui.zoneListWidget->setZoneBuilder(m_zoneBuilder); m_ui.zoneListWidget->updateUi(); createMenus(); + createToolBars(); readSettings(); + + connect(m_ui.projectSettingsAction, SIGNAL(triggered()), this, SLOT(openProjectSettings())); } LandscapeEditorWindow::~LandscapeEditorWindow() { + delete m_zoneBuilder; writeSettings(); } @@ -75,11 +78,37 @@ void LandscapeEditorWindow::open() setCursor(Qt::ArrowCursor); } +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(), false); + m_ui.zoneListWidget->updateUi(); + } + delete dialog; +} + 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); + QAction *action = menuManager->action(Core::Constants::OPEN); + 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 LandscapeEditorWindow::readSettings() { QSettings *settings = Core::ICore::instance()->settings(); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h index 61e0c7eb1..9b2ae0335 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h @@ -43,8 +43,11 @@ public Q_SLOTS: void open(); private Q_SLOTS: + void openProjectSettings(); + private: void createMenus(); + void createToolBars(); void readSettings(); void writeSettings(); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui index ac16ad9fd..3877d9732 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui @@ -24,7 +24,7 @@ - + toolBar @@ -44,6 +44,27 @@ + + + toolBar_2 + + + TopToolBarArea + + + false + + + + + + + :/icons/ic_nel_landscape_settings.png:/icons/ic_nel_landscape_settings.png + + + Project settings + + diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_model.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_model.cpp index ffcb7617b..622fd8fb8 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_model.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_model.cpp @@ -17,6 +17,7 @@ // Project includes #include "list_zones_model.h" +#include "builder_zone.h" // NeL includes #include @@ -27,15 +28,14 @@ // Qt includes #include -#include #include namespace LandscapeEditor { -ListZonesModel::ListZonesModel(int pixmapSize, QObject *parent) +ListZonesModel::ListZonesModel(int scaleRatio, QObject *parent) : QAbstractListModel(parent), - m_pixmapSize(pixmapSize) + m_scaleRatio(scaleRatio) { } @@ -46,7 +46,7 @@ ListZonesModel::~ListZonesModel() int ListZonesModel::rowCount(const QModelIndex & /* parent */) const { - return m_pixmapNameList.count(); + return m_listNames.count(); } int ListZonesModel::columnCount(const QModelIndex & /* parent */) const @@ -65,11 +65,11 @@ QVariant ListZonesModel::data(const QModelIndex &index, int role) const } else if (role == Qt::DisplayRole) { - return m_pixmapNameList.at(index.row()); + return m_listNames.at(index.row()); } else if (role == Qt::DecorationRole) { - QPixmap *pixmap = getSmallPixmap(m_pixmapNameList.at(index.row())); + QPixmap *pixmap = getPixmap(m_listNames.at(index.row())); return qVariantFromValue(*pixmap); } return QVariant(); @@ -84,73 +84,48 @@ QVariant ListZonesModel::headerData(int section, return QVariant(); } -void ListZonesModel::setSmallPixmapSize(int pixmapSize) +void ListZonesModel::setScaleRatio(int scaleRatio) { - m_pixmapSize = pixmapSize; + m_scaleRatio = scaleRatio; } void ListZonesModel::setListZones(QStringList &listZones) { beginResetModel(); - m_pixmapNameList.clear(); - m_pixmapNameList = listZones; + m_listNames.clear(); + m_listNames = listZones; endResetModel(); } void ListZonesModel::resetModel() { beginResetModel(); - Q_FOREACH(QString name, m_pixmapNameList) + QStringList listNames(m_pixmapMap.keys()); + Q_FOREACH(QString name, listNames) { QPixmap *pixmap = m_pixmapMap.value(name); delete pixmap; - QPixmap *smallPixmap = m_smallPixmapMap.value(name); - delete smallPixmap; } m_pixmapMap.clear(); - m_pixmapNameList.clear(); - m_smallPixmapMap.clear(); + m_listNames.clear(); endResetModel(); } -bool ListZonesModel::rebuildModel(const QString &zonePath, NLLIGO::CZoneBank &zoneBank) +void ListZonesModel::rebuildModel(PixmapDatabase *pixmapDatabase) { - beginResetModel(); - m_zonePath = zonePath; + resetModel(); - QProgressDialog *progressDialog = new QProgressDialog(); - progressDialog->show(); + beginResetModel(); + QStringList listNames; + listNames = pixmapDatabase->listPixmaps(); - std::vector zoneNames; - zoneBank.getCategoryValues ("zone", zoneNames); - progressDialog->setRange(0, zoneNames.size()); - for (uint i = 0; i < zoneNames.size(); ++i) + Q_FOREACH(QString name, listNames) { - QApplication::processEvents(); - progressDialog->setValue(i); - - NLLIGO::CZoneBankElement *zoneBankItem = zoneBank.getElementByZoneName (zoneNames[i]); - - // Read the texture file - QString zonePixmapName(zoneNames[i].c_str()); - uint8 sizeX = zoneBankItem->getSizeX(); - uint8 sizeY = zoneBankItem->getSizeY(); - const std::vector &rMask = zoneBankItem->getMask(); - - QPixmap *pixmap = new QPixmap(zonePath + zonePixmapName + ".png"); - if (pixmap->isNull()) - { - // Generate filled pixmap - } - QPixmap *smallPixmap = new QPixmap(pixmap->scaled(m_pixmapSize * sizeX, m_pixmapSize * sizeY)); - - m_pixmapMap.insert(zonePixmapName, pixmap); - m_smallPixmapMap.insert(zonePixmapName, smallPixmap); - + 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(); - delete progressDialog; - return true; } QPixmap *ListZonesModel::getPixmap(const QString &zoneName) const @@ -163,15 +138,4 @@ QPixmap *ListZonesModel::getPixmap(const QString &zoneName) const return result; } -QPixmap *ListZonesModel::getSmallPixmap(const QString &zoneName) const -{ - QPixmap *result = 0; - if (!m_pixmapMap.contains(zoneName)) - nlwarning("QPixmap %s not found", zoneName.toStdString().c_str()); - else - result = m_smallPixmapMap.value(zoneName); - return result; -} - - } /* namespace LandscapeEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_model.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_model.h index 16a28bf07..475416887 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_model.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_model.h @@ -31,18 +31,18 @@ namespace LandscapeEditor { +class PixmapDatabase; /** @class ListZonesModel -@brief ListZonesModel contains the image database for QGraphicsScene and -small images for QListView +@brief ListZonesModel contains the small images for QListView @details */ class ListZonesModel : public QAbstractListModel { Q_OBJECT public: - ListZonesModel(int pixmapSize = 64, QObject *parent = 0); + ListZonesModel(int scaleRatio = 4, QObject *parent = 0); ~ListZonesModel(); int rowCount(const QModelIndex &parent) const; @@ -53,30 +53,25 @@ public: /// Set size for small pixmaps /// Value should be set before calling rebuildModel - void setSmallPixmapSize(int pixmapSize); + 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); - /// Load all images(png) from zonePath, list images gets from zoneBank - bool rebuildModel(const QString &zonePath, NLLIGO::CZoneBank &zoneBank); + /// Build own pixmaps database(all images are scaled: width/scaleRatio, height/scaleRatio) from pixmapDatabase + void rebuildModel(PixmapDatabase *pixmapDatabase); - /// Get original pixmap +private: + /// Get pixmap /// @return QPixmap* if the image is in the database ; otherwise returns 0. QPixmap *getPixmap(const QString &zoneName) const; - /// Get scaled pixmap (pixmapSize * zoneSize.sizeX, pixmapSize * zoneSize.sizeY) - /// @return QPixmap* if the image is in the database ; otherwise returns 0. - QPixmap *getSmallPixmap(const QString &zoneName) const; -private: - - QString m_zonePath; - int m_pixmapSize; + int m_scaleRatio; QMap m_pixmapMap; - QMap m_smallPixmapMap; - QList m_pixmapNameList; + QStringList m_listNames; }; } /* namespace LandscapeEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp index 8dcb87383..e4e3fae0d 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp @@ -37,10 +37,14 @@ namespace LandscapeEditor ListZonesWidget::ListZonesWidget(QWidget *parent) : QWidget(parent), + 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); @@ -81,6 +85,10 @@ void ListZonesWidget::updateUi() 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); @@ -88,11 +96,8 @@ void ListZonesWidget::updateUi() m_ui.categoryTypeComboBox_4->addItems(listCategories); disableSignals(false); -} -void ListZonesWidget::setModel(QAbstractItemModel *model) -{ - m_ui.listView->setModel(model); + m_listZonesModel->rebuildModel(m_zoneBuilder->pixmapDatabase()); } void ListZonesWidget::setZoneBuilder(ZoneBuilder *zoneBuilder) @@ -201,7 +206,8 @@ void ListZonesWidget::updateListZones() QStringList listSelection; for (size_t i = 0; i < currentSelection.size(); ++i) listSelection << currentSelection[i]->getName().c_str(); - m_zoneBuilder->zoneModel()->setListZones(listSelection); + + m_listZonesModel->setListZones(listSelection); } void ListZonesWidget::disableSignals(bool block) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h index fed0134cf..049f0ebcb 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h @@ -28,10 +28,11 @@ namespace LandscapeEditor { class ZoneBuilder; +class ListZonesModel; /** @class ZoneListWidget -@brief ZoneListWidget +@brief ZoneListWidget displays list available zones in accordance with the filter settings @details */ class ListZonesWidget: public QWidget @@ -44,21 +45,19 @@ public: void updateUi(); void setZoneBuilder(ZoneBuilder *zoneBuilder); - void setModel(QAbstractItemModel *model); Q_SIGNALS: -public Q_SLOTS: +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); - -private Q_SLOTS: void updateListZones(); private: void disableSignals(bool block); + ListZonesModel *m_listZonesModel; ZoneBuilder *m_zoneBuilder; Ui::ListZonesWidget m_ui; }; /* ZoneListWidget */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.cpp new file mode 100644 index 000000000..bf095e6cf --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.cpp @@ -0,0 +1,52 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +// Project includes +#include "project_settings_dialog.h" +#include "landscape_editor_constants.h" + +#include "../core/icore.h" +#include "../core/core_constants.h" + +// NeL includes +#include + +// Qt includes +#include +#include + +namespace LandscapeEditor +{ + +ProjectSettingsDialog::ProjectSettingsDialog(const QString &dataPath, QWidget *parent) + : QDialog(parent) +{ + m_ui.setupUi(this); + m_ui.pathLineEdit->setText(dataPath); + setFixedHeight(sizeHint().height()); +} + +ProjectSettingsDialog::~ProjectSettingsDialog() +{ +} + +QString ProjectSettingsDialog::dataPath() const +{ + return m_ui.pathLineEdit->text(); +} + +} /* namespace LandscapeEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.h new file mode 100644 index 000000000..74443e3f1 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.h @@ -0,0 +1,46 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +#ifndef PROJECT_SETTINGS_DIALOG_H +#define PROJECT_SETTINGS_DIALOG_H + +// Project includes +#include "ui_project_settings_dialog.h" + +// Qt includes + +namespace LandscapeEditor +{ + +class ProjectSettingsDialog: public QDialog +{ + Q_OBJECT + +public: + ProjectSettingsDialog(const QString &dataPath, QWidget *parent = 0); + ~ProjectSettingsDialog(); + + QString dataPath() const; + +private: + + Ui::ProjectSettingsDialog m_ui; +}; /* class ProjectSettingsDialog */ + +} /* namespace LandscapeEditor */ + +#endif // PROJECT_SETTINGS_DIALOG_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.ui new file mode 100644 index 000000000..bb94fcc0d --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.ui @@ -0,0 +1,97 @@ + + + ProjectSettingsDialog + + + + 0 + 0 + 419 + 93 + + + + Project settings + + + + :/icons/ic_nel_landscape_settings.png:/icons/ic_nel_landscape_settings.png + + + + + + Data directory: + + + + + + + + + + ... + + + + + + + Context: + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + + + buttonBox + accepted() + ProjectSettingsDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + ProjectSettingsDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + From 894a41cf97a4584cc4c76da6c9947037513e71ea Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Thu, 9 Jun 2011 02:11:50 +0300 Subject: [PATCH 04/89] Changed: #1301 Added select path button in project settings dialog. Main window landscape editor is saving own state. --HG-- branch : gsoc2011-worldeditorqt --- .../plugins/landscape_editor/CMakeLists.txt | 1 + .../plugins/landscape_editor/builder_zone.cpp | 1 + .../plugins/landscape_editor/builder_zone.h | 4 +- .../landscape_editor_constants.h | 2 + .../landscape_editor_window.cpp | 14 +++++ .../landscape_editor_window.h | 5 +- .../landscape_editor_window.ui | 17 +++++- .../landscape_editor/landscape_view.cpp | 52 +++++++++++++++++++ .../plugins/landscape_editor/landscape_view.h | 49 +++++++++++++++++ .../landscape_editor/list_zones_model.cpp | 16 +++--- .../landscape_editor/list_zones_widget.ui | 9 +++- .../project_settings_dialog.cpp | 9 ++++ .../project_settings_dialog.h | 3 ++ 13 files changed, 168 insertions(+), 14 deletions(-) create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt index 227210366..e189af74b 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt @@ -15,6 +15,7 @@ SET(OVQT_PLUGIN_LANDSCAPE_EDITOR_HDR landscape_editor_plugin.h list_zones_model.h list_zones_widget.h landscape_actions.h + landscape_view.h project_settings_dialog.h ) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp index 3db771224..288a4b1be 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp @@ -164,6 +164,7 @@ bool ZoneBuilder::initZoneBank (const QString &pathName) 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; } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h index f69c2f7fb..f43bb7d7e 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h @@ -67,8 +67,8 @@ private: /** @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 +@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 diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_constants.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_constants.h index 52775f4c4..6875ddfab 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_constants.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_constants.h @@ -26,6 +26,8 @@ const char * const LANDSCAPE_EDITOR_PLUGIN = "LandscapeEditor"; //settings const char * const LANDSCAPE_EDITOR_SECTION = "LandscapeEditor"; +const char * const LANDSCAPE_WINDOW_STATE = "LandscapeWindowState"; +const char * const LANDSCAPE_WINDOW_GEOMETRY = "LandscapeWindowGeometry"; //resources const char * const ICON_LANDSCAPE_ITEM = ":/icons/ic_nel_landscape_item.png"; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp index 1b8716326..c17de1f43 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp @@ -18,6 +18,8 @@ // Project includes #include "landscape_editor_window.h" #include "landscape_editor_constants.h" +#include "builder_zone.h" +#include "landscape_scene.h" #include "project_settings_dialog.h" #include "../core/icore.h" @@ -30,6 +32,8 @@ // Qt includes #include #include +#include +#include namespace LandscapeEditor { @@ -45,6 +49,12 @@ LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent) m_zoneBuilder->init("e:/-nel-/install/continents/newbieland", false); m_ui.zoneListWidget->setZoneBuilder(m_zoneBuilder); m_ui.zoneListWidget->updateUi(); + + m_landscapeScene = new LandscapeScene(this); + m_ui.graphicsView->setScene(m_landscapeScene); + m_ui.graphicsView->setViewport(new QGLWidget(QGLFormat(QGL::DoubleBuffer | QGL::SampleBuffers))); + + createMenus(); createToolBars(); readSettings(); @@ -113,6 +123,8 @@ 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()); settings->endGroup(); } @@ -120,6 +132,8 @@ 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->endGroup(); settings->sync(); } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h index 9b2ae0335..1fecd9f03 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h @@ -20,7 +20,6 @@ // Project includes #include "ui_landscape_editor_window.h" -#include "builder_zone.h" // Qt includes #include @@ -28,6 +27,9 @@ namespace LandscapeEditor { +class LandscapeScene; +class ZoneBuilder; + class LandscapeEditorWindow: public QMainWindow { Q_OBJECT @@ -51,6 +53,7 @@ private: void readSettings(); void writeSettings(); + LandscapeScene *m_landscapeScene; ZoneBuilder *m_zoneBuilder; QUndoStack *m_undoStack; Ui::LandscapeEditorWindow m_ui; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui index 3877d9732..1361cd2bc 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui @@ -19,8 +19,18 @@ + + 3 + + + 3 + - + + + QGraphicsView::NoDrag + + @@ -73,6 +83,11 @@
list_zones_widget.h
1
+ + LandscapeEditor::LandscapeView + QGraphicsView +
landscape_view.h
+
diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp new file mode 100644 index 000000000..79b33599e --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp @@ -0,0 +1,52 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +// Project includes +#include "landscape_view.h" +#include "landscape_editor_constants.h" + +#include "../core/icore.h" +#include "../core/core_constants.h" + +// NeL includes +#include + +// Qt includes + + +namespace LandscapeEditor +{ + +LandscapeView::LandscapeView(QWidget *parent) + : QGraphicsView(parent) +{ + setDragMode(ScrollHandDrag); +} + +LandscapeView::~LandscapeView() +{ +} + +void LandscapeView::wheelEvent(QWheelEvent *event) +{ + double numDegrees = event->delta() / 8.0; + double numSteps = numDegrees / 15.0; + double factor = std::pow(1.125, numSteps); + scale(factor, factor); +} + +} /* namespace LandscapeEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h new file mode 100644 index 000000000..db79b79ff --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h @@ -0,0 +1,49 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +#ifndef LANDSCAPE_VIEW_H +#define LANDSCAPE_VIEW_H + +// Project includes + +// Qt includes +#include +#include + +namespace LandscapeEditor +{ + +class LandscapeView: public QGraphicsView +{ + Q_OBJECT + +public: + LandscapeView(QWidget *parent = 0); + ~LandscapeView(); + +protected: + void wheelEvent(QWheelEvent *event); + +private Q_SLOTS: + +private: + +}; /* class LandscapeView */ + +} /* namespace LandscapeEditor */ + +#endif // LANDSCAPE_VIEW_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_model.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_model.cpp index 622fd8fb8..57e8683c0 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_model.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_model.cpp @@ -59,28 +59,26 @@ QVariant ListZonesModel::data(const QModelIndex &index, int role) const if (!index.isValid()) return QVariant(); - if (role == Qt::TextAlignmentRole) + switch (role) { + case Qt::TextAlignmentRole: return int(Qt::AlignLeft | Qt::AlignVCenter); - } - else if (role == Qt::DisplayRole) - { + case Qt::DisplayRole: return m_listNames.at(index.row()); - } - else if (role == Qt::DecorationRole) + case Qt::DecorationRole: { QPixmap *pixmap = getPixmap(m_listNames.at(index.row())); return qVariantFromValue(*pixmap); } - return QVariant(); + default: + return QVariant(); + } } QVariant ListZonesModel::headerData(int section, Qt::Orientation /* orientation */, int role) const { - if (role != Qt::DisplayRole) - return QVariant(); return QVariant(); } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.ui index 585371cb7..289cb45dd 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.ui +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.ui @@ -290,7 +290,14 @@
- + + + false + + + QAbstractItemView::ScrollPerPixel + + diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.cpp index bf095e6cf..3acd3ff66 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.cpp @@ -28,6 +28,7 @@ // Qt includes #include #include +#include namespace LandscapeEditor { @@ -38,6 +39,7 @@ ProjectSettingsDialog::ProjectSettingsDialog(const QString &dataPath, QWidget *p m_ui.setupUi(this); m_ui.pathLineEdit->setText(dataPath); setFixedHeight(sizeHint().height()); + connect(m_ui.selectPathButton, SIGNAL(clicked()), this, SLOT(selectPath())); } ProjectSettingsDialog::~ProjectSettingsDialog() @@ -49,4 +51,11 @@ 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 */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.h index 74443e3f1..abb93ab81 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.h @@ -36,6 +36,9 @@ public: QString dataPath() const; +private Q_SLOTS: + void selectPath(); + private: Ui::ProjectSettingsDialog m_ui; From 02e34cd7f8e2a8667ba46472b2f3bcf69aff8f2a Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Tue, 14 Jun 2011 12:26:41 +0300 Subject: [PATCH 05/89] Changed: #1301 Experiments with undo\redo and QGraphicsScene. --HG-- branch : gsoc2011-worldeditorqt --- .../plugins/landscape_editor/builder_zone.h | 29 +++++++++++ .../landscape_editor/landscape_actions.cpp | 31 ++++++++++++ .../landscape_editor/landscape_actions.h | 22 ++++++++ .../landscape_editor_window.cpp | 6 +-- .../landscape_editor_window.ui | 8 +++ .../landscape_editor/landscape_scene.cpp | 50 ++++++++++++++++++- .../landscape_editor/landscape_scene.h | 19 ++++++- .../landscape_editor/landscape_view.cpp | 43 ++++++++++++---- .../plugins/landscape_editor/landscape_view.h | 6 ++- .../landscape_editor/list_zones_widget.cpp | 12 ++++- .../landscape_editor/list_zones_widget.h | 3 +- 11 files changed, 209 insertions(+), 20 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h index f43bb7d7e..0ccbf4e23 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h @@ -36,6 +36,35 @@ namespace LandscapeEditor { +// Data +struct LigoData +{ + uint32 PosX; + uint32 PosY; + qreal Scale; + uint8 Rot; + uint8 Flip; + std::string ZoneName; + std::string SharingMatNames[4]; + uint8 SharingCutEdges[4]; + 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 PixmapDatabase @brief PixmapDatabase contains the image database diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp index f0b86dd8e..14cdb4f4b 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp @@ -17,6 +17,7 @@ // Project includes #include "landscape_actions.h" +#include "builder_zone.h" // NeL includes #include @@ -25,4 +26,34 @@ namespace LandscapeEditor { + +ActionLigoTile::ActionLigoTile(const LigoData &data, ZoneBuilder *zoneBuilder, QGraphicsScene *scene, QUndoCommand *parent) + : QUndoCommand(parent), + m_item(0), + m_zoneBuilder(zoneBuilder), + m_scene(scene) +{ + m_ligoData = data; +} + +ActionLigoTile::~ActionLigoTile() +{ +} + +void ActionLigoTile::undo() +{ + m_scene->removeItem(m_item); + delete m_item; + m_item = 0; +} + +void ActionLigoTile::redo() +{ + QPixmap *pixmap = m_zoneBuilder->pixmapDatabase()->pixmap(QString(m_ligoData.ZoneName.c_str())); + m_item = new QGraphicsPixmapItem(*pixmap, 0, m_scene); + m_item->setPos(m_ligoData.PosX, m_ligoData.PosY); + m_item->setScale(m_ligoData.Scale); + setText(QObject::tr("Add tile(%1, %2)").arg(m_ligoData.PosX).arg(m_ligoData.PosY)); +} + } /* namespace LandscapeEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h index fdcda5451..76cb92762 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h @@ -19,13 +19,35 @@ #define LANDSCAPE_ACTIONS_H // Project includes +#include "builder_zone.h" // NeL includes // Qt includes +#include +#include +#include namespace LandscapeEditor { +class ZoneBuilder; + +class ActionLigoTile : public QUndoCommand +{ +public: + ActionLigoTile(const LigoData &data, ZoneBuilder *zoneBuilder, QGraphicsScene *scene, QUndoCommand *parent = 0); + ~ActionLigoTile(); + + virtual void undo(); + virtual void redo(); + +private: + + LigoData m_ligoData; + QGraphicsPixmapItem *m_item; + ZoneBuilder *m_zoneBuilder; + QGraphicsScene *m_scene; +}; } /* namespace LandscapeEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp index c17de1f43..90c712e6c 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp @@ -33,7 +33,6 @@ #include #include #include -#include namespace LandscapeEditor { @@ -50,10 +49,9 @@ LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent) m_ui.zoneListWidget->setZoneBuilder(m_zoneBuilder); m_ui.zoneListWidget->updateUi(); - m_landscapeScene = new LandscapeScene(this); + m_landscapeScene = new LandscapeScene(m_undoStack, m_ui.zoneListWidget, m_zoneBuilder, this); m_ui.graphicsView->setScene(m_landscapeScene); - m_ui.graphicsView->setViewport(new QGLWidget(QGLFormat(QGL::DoubleBuffer | QGL::SampleBuffers))); - + //m_ui.graphicsView->setViewport(new QGLWidget(QGLFormat(QGL::DoubleBuffer | QGL::SampleBuffers))); createMenus(); createToolBars(); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui index 1361cd2bc..bb14576a2 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui @@ -27,6 +27,14 @@ + + + 0.000000000000000 + 0.000000000000000 + 99999.000000000000000 + 99999.000000000000000 + + QGraphicsView::NoDrag diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp index f491dfa2b..993b6ec9c 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp @@ -17,22 +17,68 @@ // Project includes #include "landscape_scene.h" +#include "builder_zone.h" +#include "landscape_actions.h" +#include "list_zones_widget.h" // NeL includes #include // Qt includes +#include +#include namespace LandscapeEditor { -LandscapeScene::LandscapeScene(QObject *parent) - : QGraphicsScene(parent) +LandscapeScene::LandscapeScene(QUndoStack *undoStack, ListZonesWidget *listZonesWidget, ZoneBuilder *zoneBuilder, QObject *parent) + : QGraphicsScene(parent), + m_undoStack(undoStack), + m_listZonesWidget(listZonesWidget), + m_zoneBuilder(zoneBuilder) { + m_cellSize = 160; + createBackgroundPixmap(); } LandscapeScene::~LandscapeScene() { } +void LandscapeScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) +{ + if (mouseEvent->button() != Qt::LeftButton) + return; + + qreal x = mouseEvent->scenePos().rx(); + qreal y = mouseEvent->scenePos().ry(); + if ((x < 0) || (y < 0)) + return; + + LigoData ligoData = m_listZonesWidget->currentLigoData(); + if (ligoData.ZoneName == "") + return; + + ligoData.PosX = m_cellSize * int(x / m_cellSize);; + ligoData.PosY = m_cellSize * int(y / m_cellSize); + ligoData.Scale = m_cellSize / 256.0; + + ActionLigoTile *action = new ActionLigoTile(ligoData, m_zoneBuilder, this); + m_undoStack->push(action); + + QGraphicsScene::mousePressEvent(mouseEvent); +} + +void LandscapeScene::createBackgroundPixmap() +{ + QPixmap pixmap(QSize(m_cellSize, m_cellSize)); + QPainter painter(&pixmap); + //painter.setRenderHint(QPainter::Antialiasing, true); + painter.setBrush(QBrush(Qt::lightGray)); + painter.setPen(QPen(Qt::black, 3, Qt::DotLine)); + painter.drawRect(0, 0, pixmap.width(), pixmap.height()); + + setBackgroundBrush(pixmap); +} + } /* namespace LandscapeEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h index d4fb91c78..b4a7a68de 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h @@ -23,18 +23,33 @@ // NeL includes // Qt includes -#include +#include +#include +#include namespace LandscapeEditor { +class ZoneBuilder; +class ListZonesWidget; class LandscapeScene : public QGraphicsScene { Q_OBJECT public: - LandscapeScene(QObject *parent = 0); + LandscapeScene(QUndoStack *undoStack, ListZonesWidget *listZonesWidget, ZoneBuilder *zoneBuilder, QObject *parent = 0); virtual ~LandscapeScene(); + +protected: + void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent); + +private: + void createBackgroundPixmap(); + + int m_cellSize; + ListZonesWidget *m_listZonesWidget; + QUndoStack *m_undoStack; + ZoneBuilder *m_zoneBuilder; }; } /* namespace LandscapeEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp index 79b33599e..4bd202b7c 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp @@ -26,27 +26,52 @@ #include // Qt includes - +#include namespace LandscapeEditor { LandscapeView::LandscapeView(QWidget *parent) - : QGraphicsView(parent) + : QGraphicsView(parent), + m_moveMouse(false) { - setDragMode(ScrollHandDrag); + setDragMode(ScrollHandDrag); + setTransformationAnchor(AnchorUnderMouse); } LandscapeView::~LandscapeView() { } -void LandscapeView::wheelEvent(QWheelEvent *event) -{ - double numDegrees = event->delta() / 8.0; - double numSteps = numDegrees / 15.0; - double factor = std::pow(1.125, numSteps); - scale(factor, factor); +void LandscapeView::wheelEvent(QWheelEvent *event) +{ + double numDegrees = event->delta() / 8.0; + double numSteps = numDegrees / 15.0; + double factor = std::pow(1.125, numSteps); + scale(factor, factor); +} + +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); } } /* namespace LandscapeEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h index db79b79ff..4ac090af6 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h @@ -36,12 +36,16 @@ public: ~LandscapeView(); protected: - void wheelEvent(QWheelEvent *event); + virtual void wheelEvent(QWheelEvent *event); + virtual void mousePressEvent(QMouseEvent *event); + virtual void mouseMoveEvent(QMouseEvent *event); + virtual void mouseReleaseEvent(QMouseEvent *event); private Q_SLOTS: private: + bool m_moveMouse; }; /* class LandscapeView */ } /* namespace LandscapeEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp index e4e3fae0d..56e362181 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp @@ -17,7 +17,6 @@ // Project includes #include "list_zones_widget.h" -#include "builder_zone.h" #include "list_zones_model.h" // NeL includes @@ -31,6 +30,7 @@ // Qt includes #include +#include namespace LandscapeEditor { @@ -100,6 +100,16 @@ void ListZonesWidget::updateUi() m_listZonesModel->rebuildModel(m_zoneBuilder->pixmapDatabase()); } +LigoData ListZonesWidget::currentLigoData() const +{ + LigoData ligoData; + ligoData.ZoneName = ""; + QModelIndex index = m_ui.listView->currentIndex(); + if (index.isValid()) + ligoData.ZoneName = index.data().toString().toStdString(); + return ligoData; +} + void ListZonesWidget::setZoneBuilder(ZoneBuilder *zoneBuilder) { m_zoneBuilder = zoneBuilder; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h index 049f0ebcb..b1a6525fc 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h @@ -20,6 +20,7 @@ // Project includes #include "ui_list_zones_widget.h" +#include "builder_zone.h" // NeL includes @@ -27,7 +28,6 @@ namespace LandscapeEditor { -class ZoneBuilder; class ListZonesModel; /** @@ -45,6 +45,7 @@ public: void updateUi(); void setZoneBuilder(ZoneBuilder *zoneBuilder); + LigoData currentLigoData() const; Q_SIGNALS: private Q_SLOTS: From 0a870aeb12eb612dd7583a0778b4f25e367fa6b4 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Thu, 16 Jun 2011 09:32:49 +0300 Subject: [PATCH 06/89] Changed: #1301 Added max\min scale view. Improved drawing of the grid. --HG-- branch : gsoc2011-worldeditorqt --- .../landscape_editor/landscape_actions.cpp | 44 +++++++++++-- .../landscape_editor/landscape_actions.h | 28 ++++++++- .../landscape_editor_window.cpp | 3 +- .../landscape_editor_window.ui | 18 ++++++ .../landscape_editor/landscape_scene.cpp | 15 +---- .../landscape_editor/landscape_scene.h | 3 +- .../landscape_editor/landscape_view.cpp | 61 +++++++++++++++++++ .../plugins/landscape_editor/landscape_view.h | 17 ++++-- 8 files changed, 161 insertions(+), 28 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp index 14cdb4f4b..5582de2d7 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp @@ -27,7 +27,42 @@ namespace LandscapeEditor { -ActionLigoTile::ActionLigoTile(const LigoData &data, ZoneBuilder *zoneBuilder, QGraphicsScene *scene, QUndoCommand *parent) +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, ZoneBuilder *zoneBuilder, QGraphicsScene *scene, QUndoCommand *parent) : QUndoCommand(parent), m_item(0), m_zoneBuilder(zoneBuilder), @@ -36,23 +71,24 @@ ActionLigoTile::ActionLigoTile(const LigoData &data, ZoneBuilder *zoneBuilder, Q m_ligoData = data; } -ActionLigoTile::~ActionLigoTile() +LigoTileCommand::~LigoTileCommand() { } -void ActionLigoTile::undo() +void LigoTileCommand::undo() { m_scene->removeItem(m_item); delete m_item; m_item = 0; } -void ActionLigoTile::redo() +void LigoTileCommand::redo() { QPixmap *pixmap = m_zoneBuilder->pixmapDatabase()->pixmap(QString(m_ligoData.ZoneName.c_str())); m_item = new QGraphicsPixmapItem(*pixmap, 0, m_scene); m_item->setPos(m_ligoData.PosX, m_ligoData.PosY); m_item->setScale(m_ligoData.Scale); + m_item->setTransformationMode(Qt::SmoothTransformation); setText(QObject::tr("Add tile(%1, %2)").arg(m_ligoData.PosX).arg(m_ligoData.PosY)); } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h index 76cb92762..ff9c9dde0 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h @@ -32,11 +32,33 @@ namespace LandscapeEditor { class ZoneBuilder; -class ActionLigoTile : public QUndoCommand +class OpenLandscapeCommand: public QUndoCommand { public: - ActionLigoTile(const LigoData &data, ZoneBuilder *zoneBuilder, QGraphicsScene *scene, QUndoCommand *parent = 0); - ~ActionLigoTile(); + OpenLandscapeCommand(const QString &fileName, QUndoCommand *parent = 0); + ~OpenLandscapeCommand(); + virtual void undo(); + virtual void redo(); +private: + + QString m_fileName; +}; + +class NewLandscapeCommand: public QUndoCommand +{ +public: + NewLandscapeCommand(QUndoCommand *parent = 0); + ~NewLandscapeCommand(); + virtual void undo(); + virtual void redo(); +private: +}; + +class LigoTileCommand: public QUndoCommand +{ +public: + LigoTileCommand(const LigoData &data, ZoneBuilder *zoneBuilder, QGraphicsScene *scene, QUndoCommand *parent = 0); + ~LigoTileCommand(); virtual void undo(); virtual void redo(); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp index 90c712e6c..59a4553b9 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp @@ -51,13 +51,14 @@ LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent) m_landscapeScene = new LandscapeScene(m_undoStack, m_ui.zoneListWidget, m_zoneBuilder, this); m_ui.graphicsView->setScene(m_landscapeScene); - //m_ui.graphicsView->setViewport(new QGLWidget(QGLFormat(QGL::DoubleBuffer | QGL::SampleBuffers))); + m_ui.graphicsView->setViewport(new QGLWidget(QGLFormat(QGL::DoubleBuffer | QGL::SampleBuffers))); createMenus(); createToolBars(); readSettings(); connect(m_ui.projectSettingsAction, SIGNAL(triggered()), this, SLOT(openProjectSettings())); + connect(m_ui.enableGridAction, SIGNAL(toggled(bool)), m_ui.graphicsView, SLOT(setVisibleGrid(bool))); } LandscapeEditorWindow::~LandscapeEditorWindow() diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui index bb14576a2..ff3121d04 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui @@ -73,6 +73,7 @@ false + @@ -83,6 +84,23 @@ Project settings + + + true + + + true + + + EnableGrid + + + Show/Hide Grid + + + Ctrl+G + + diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp index 993b6ec9c..3b1ddd9fb 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp @@ -38,7 +38,6 @@ LandscapeScene::LandscapeScene(QUndoStack *undoStack, ListZonesWidget *listZones m_zoneBuilder(zoneBuilder) { m_cellSize = 160; - createBackgroundPixmap(); } LandscapeScene::~LandscapeScene() @@ -63,22 +62,10 @@ void LandscapeScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) ligoData.PosY = m_cellSize * int(y / m_cellSize); ligoData.Scale = m_cellSize / 256.0; - ActionLigoTile *action = new ActionLigoTile(ligoData, m_zoneBuilder, this); + LigoTileCommand *action = new LigoTileCommand(ligoData, m_zoneBuilder, this); m_undoStack->push(action); QGraphicsScene::mousePressEvent(mouseEvent); } -void LandscapeScene::createBackgroundPixmap() -{ - QPixmap pixmap(QSize(m_cellSize, m_cellSize)); - QPainter painter(&pixmap); - //painter.setRenderHint(QPainter::Antialiasing, true); - painter.setBrush(QBrush(Qt::lightGray)); - painter.setPen(QPen(Qt::black, 3, Qt::DotLine)); - painter.drawRect(0, 0, pixmap.width(), pixmap.height()); - - setBackgroundBrush(pixmap); -} - } /* namespace LandscapeEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h index b4a7a68de..80417d4ff 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h @@ -41,10 +41,9 @@ public: virtual ~LandscapeScene(); protected: - void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent); + virtual void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent); private: - void createBackgroundPixmap(); int m_cellSize; ListZonesWidget *m_listZonesWidget; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp index 4bd202b7c..26dd386ed 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp @@ -33,21 +33,55 @@ namespace LandscapeEditor LandscapeView::LandscapeView(QWidget *parent) : QGraphicsView(parent), + m_visibleGrid(true), m_moveMouse(false) { setDragMode(ScrollHandDrag); setTransformationAnchor(AnchorUnderMouse); + setBackgroundBrush(QBrush(Qt::lightGray)); + //setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate); + //setRenderHints(QPainter::Antialiasing); + 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; + + // hack for repaint view + translate(0.0001, 0.0001); +} + 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); } @@ -74,4 +108,31 @@ void LandscapeView::mouseReleaseEvent(QMouseEvent *event) QGraphicsView::mouseReleaseEvent(event); } +void LandscapeView::drawForeground(QPainter *painter, const QRectF &rect) +{ + if (!m_visibleGrid) + return; + + qreal scaleFactor = transform().m11(); + painter->setPen(QPen(Qt::white, 1 / scaleFactor, Qt::SolidLine)); + + // draw grid + qreal left = m_cellSize * int(rect.left() / m_cellSize); + qreal top = m_cellSize * int(rect.top() / m_cellSize); + + // draw vertical lines + while (left < rect.right()) + { + painter->drawLine(int(left), int(rect.bottom()), int(left), int(rect.top())); + left += m_cellSize; + } + + // draw horizontal lines + while (top < rect.bottom()) + { + painter->drawLine(int(rect.left()), int(top), int(rect.right()), int(top)); + top += m_cellSize; + } +} + } /* namespace LandscapeEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h index 4ac090af6..2ae251fee 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h @@ -19,6 +19,7 @@ #define LANDSCAPE_VIEW_H // Project includes +#include "landscape_editor_global.h" // Qt includes #include @@ -27,24 +28,32 @@ namespace LandscapeEditor { -class LandscapeView: public QGraphicsView +class LANDSCAPE_EDITOR_EXPORT LandscapeView: public QGraphicsView { Q_OBJECT public: LandscapeView(QWidget *parent = 0); - ~LandscapeView(); + virtual ~LandscapeView(); + bool isVisibleGrid() const; + +public Q_SLOTS: + void setVisibleGrid(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); - -private Q_SLOTS: + virtual void drawForeground(QPainter *painter, const QRectF &rect); private: + bool m_visibleGrid; + int m_numSteps, m_maxSteps; + int m_cellSize; bool m_moveMouse; }; /* class LandscapeView */ From 7099b96a90fc438961a43172322ffe344cd007e7 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Tue, 21 Jun 2011 10:14:46 +0300 Subject: [PATCH 07/89] Changed: #1301 Added load landscape from file. Added initial snapshot dialog. --HG-- branch : gsoc2011-worldeditorqt --- .../plugins/landscape_editor/CMakeLists.txt | 2 + .../plugins/landscape_editor/builder_zone.h | 29 --- .../landscape_editor/landscape_actions.cpp | 40 +++- .../landscape_editor/landscape_actions.h | 37 +++- .../landscape_editor_window.cpp | 29 +++ .../landscape_editor_window.h | 4 + .../landscape_editor_window.ui | 6 + .../landscape_editor/landscape_scene.cpp | 164 +++++++++++++- .../landscape_editor/landscape_scene.h | 39 ++++ .../landscape_editor/landscape_view.cpp | 6 +- .../landscape_editor/list_zones_widget.cpp | 3 + .../landscape_editor/list_zones_widget.h | 1 + .../landscape_editor/list_zones_widget.ui | 10 +- .../project_settings_dialog.ui | 14 +- .../landscape_editor/shapshot_dialog.ui | 208 ++++++++++++++++++ .../landscape_editor/snapshot_dialog.cpp | 45 ++++ .../landscape_editor/snapshot_dialog.h | 47 ++++ .../landscape_editor/zone_region_editor.cpp | 119 ++++++++++ .../landscape_editor/zone_region_editor.h | 62 ++++++ 19 files changed, 793 insertions(+), 72 deletions(-) create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/shapshot_dialog.ui create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/snapshot_dialog.cpp create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/snapshot_dialog.h create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.cpp create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.h diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt index e189af74b..8c4278c46 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt @@ -17,11 +17,13 @@ SET(OVQT_PLUGIN_LANDSCAPE_EDITOR_HDR landscape_editor_plugin.h landscape_actions.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) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h index 0ccbf4e23..f43bb7d7e 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h @@ -36,35 +36,6 @@ namespace LandscapeEditor { -// Data -struct LigoData -{ - uint32 PosX; - uint32 PosY; - qreal Scale; - uint8 Rot; - uint8 Flip; - std::string ZoneName; - std::string SharingMatNames[4]; - uint8 SharingCutEdges[4]; - 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 PixmapDatabase @brief PixmapDatabase contains the image database diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp index 5582de2d7..84d59ba8d 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp @@ -62,34 +62,54 @@ void NewLandscapeCommand::redo() { } -LigoTileCommand::LigoTileCommand(const LigoData &data, ZoneBuilder *zoneBuilder, QGraphicsScene *scene, QUndoCommand *parent) +AddLigoTileCommand::AddLigoTileCommand(const LigoData &data, LandscapeScene *scene, QUndoCommand *parent) : QUndoCommand(parent), m_item(0), - m_zoneBuilder(zoneBuilder), m_scene(scene) { m_ligoData = data; } -LigoTileCommand::~LigoTileCommand() +AddLigoTileCommand::~AddLigoTileCommand() { } -void LigoTileCommand::undo() +void AddLigoTileCommand::undo() { m_scene->removeItem(m_item); delete m_item; m_item = 0; } -void LigoTileCommand::redo() +void AddLigoTileCommand::redo() { - QPixmap *pixmap = m_zoneBuilder->pixmapDatabase()->pixmap(QString(m_ligoData.ZoneName.c_str())); - m_item = new QGraphicsPixmapItem(*pixmap, 0, m_scene); - m_item->setPos(m_ligoData.PosX, m_ligoData.PosY); - m_item->setScale(m_ligoData.Scale); - m_item->setTransformationMode(Qt::SmoothTransformation); + m_item = m_scene->createZoneItem(m_ligoData); setText(QObject::tr("Add tile(%1, %2)").arg(m_ligoData.PosX).arg(m_ligoData.PosY)); } +DelLigoTileCommand::DelLigoTileCommand(const LigoData &data, LandscapeScene *scene, QUndoCommand *parent) + : QUndoCommand(parent), + m_item(0), + m_scene(scene) +{ + m_ligoData = data; +} + +DelLigoTileCommand::~DelLigoTileCommand() +{ +} + +void DelLigoTileCommand::undo() +{ + m_item = m_scene->createZoneItem(m_ligoData); +} + +void DelLigoTileCommand::redo() +{ + m_item = m_scene->itemAt(m_ligoData.PosX * m_scene->cellSize(), m_ligoData.PosY * m_scene->cellSize()); + delete m_item; + m_item = 0; + setText(QObject::tr("Del tile(%1, %2)").arg(m_ligoData.PosX).arg(m_ligoData.PosY)); +} + } /* namespace LandscapeEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h index ff9c9dde0..7bbd1bd96 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h @@ -20,23 +20,24 @@ // Project includes #include "builder_zone.h" +#include "landscape_scene.h" // NeL includes // Qt includes #include #include -#include +#include namespace LandscapeEditor { -class ZoneBuilder; class OpenLandscapeCommand: public QUndoCommand { public: OpenLandscapeCommand(const QString &fileName, QUndoCommand *parent = 0); - ~OpenLandscapeCommand(); + virtual ~OpenLandscapeCommand(); + virtual void undo(); virtual void redo(); private: @@ -48,17 +49,34 @@ class NewLandscapeCommand: public QUndoCommand { public: NewLandscapeCommand(QUndoCommand *parent = 0); - ~NewLandscapeCommand(); + virtual ~NewLandscapeCommand(); + virtual void undo(); virtual void redo(); private: }; -class LigoTileCommand: public QUndoCommand +class AddLigoTileCommand: public QUndoCommand +{ +public: + AddLigoTileCommand(const LigoData &data, LandscapeScene *scene, QUndoCommand *parent = 0); + virtual ~AddLigoTileCommand(); + + virtual void undo(); + virtual void redo(); + +private: + + LigoData m_ligoData; + QGraphicsItem *m_item; + LandscapeScene *m_scene; +}; + +class DelLigoTileCommand: public QUndoCommand { public: - LigoTileCommand(const LigoData &data, ZoneBuilder *zoneBuilder, QGraphicsScene *scene, QUndoCommand *parent = 0); - ~LigoTileCommand(); + DelLigoTileCommand(const LigoData &data, LandscapeScene *scene, QUndoCommand *parent = 0); + virtual ~DelLigoTileCommand(); virtual void undo(); virtual void redo(); @@ -66,9 +84,8 @@ public: private: LigoData m_ligoData; - QGraphicsPixmapItem *m_item; - ZoneBuilder *m_zoneBuilder; - QGraphicsScene *m_scene; + QGraphicsItem *m_item; + LandscapeScene *m_scene; }; } /* namespace LandscapeEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp index 59a4553b9..5ec3f6196 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp @@ -21,6 +21,7 @@ #include "builder_zone.h" #include "landscape_scene.h" #include "project_settings_dialog.h" +#include "snapshot_dialog.h" #include "../core/icore.h" #include "../core/imenu_manager.h" @@ -51,6 +52,7 @@ LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent) m_landscapeScene = new LandscapeScene(m_undoStack, m_ui.zoneListWidget, m_zoneBuilder, this); m_ui.graphicsView->setScene(m_landscapeScene); + //m_ui.graphicsView->setViewport(new QGLWidget(QGLFormat(QGL::DoubleBuffer))); m_ui.graphicsView->setViewport(new QGLWidget(QGLFormat(QGL::DoubleBuffer | QGL::SampleBuffers))); createMenus(); @@ -58,6 +60,7 @@ LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent) readSettings(); 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))); } @@ -83,6 +86,14 @@ void LandscapeEditorWindow::open() { QStringList list = fileNames; _lastDir = QFileInfo(list.front()).absolutePath(); + Q_FOREACH(QString fileName, fileNames) + { + m_zoneRegionEditor.load(fileName.toStdString()); + m_landscapeScene->processZoneRegion(m_zoneRegionEditor.zoneRegion()); + m_landscapeScene->setCurrentZoneRegion(&m_zoneRegionEditor.zoneRegion()); + m_ui.graphicsView->centerOn(m_zoneRegionEditor.zoneRegion().getMinX() * m_landscapeScene->cellSize(), + abs(m_zoneRegionEditor.zoneRegion().getMinY()) * m_landscapeScene->cellSize()); + } } setCursor(Qt::ArrowCursor); } @@ -100,6 +111,24 @@ void LandscapeEditorWindow::openProjectSettings() 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); + m_landscapeScene->snapshot(fileName, 128); + setCursor(Qt::ArrowCursor); + } + delete dialog; +} + void LandscapeEditorWindow::createMenus() { Core::IMenuManager *menuManager = Core::ICore::instance()->menuManager(); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h index 1fecd9f03..311a65013 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h @@ -20,6 +20,7 @@ // Project includes #include "ui_landscape_editor_window.h" +#include "zone_region_editor.h" // Qt includes #include @@ -46,6 +47,7 @@ public Q_SLOTS: private Q_SLOTS: void openProjectSettings(); + void openSnapshotDialog(); private: void createMenus(); @@ -53,6 +55,8 @@ private: void readSettings(); void writeSettings(); + ZoneRegionEditor m_zoneRegionEditor; + LandscapeScene *m_landscapeScene; ZoneBuilder *m_zoneBuilder; QUndoStack *m_undoStack; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui index ff3121d04..212d0eb13 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui @@ -72,6 +72,7 @@ false + @@ -101,6 +102,11 @@ Ctrl+G + + + snapshot + + diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp index 3b1ddd9fb..96ad0879b 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp @@ -27,6 +27,7 @@ // Qt includes #include #include +#include namespace LandscapeEditor { @@ -35,7 +36,8 @@ LandscapeScene::LandscapeScene(QUndoStack *undoStack, ListZonesWidget *listZones : QGraphicsScene(parent), m_undoStack(undoStack), m_listZonesWidget(listZonesWidget), - m_zoneBuilder(zoneBuilder) + m_zoneBuilder(zoneBuilder), + m_zoneRegion(0) { m_cellSize = 160; } @@ -44,27 +46,167 @@ LandscapeScene::~LandscapeScene() { } -void LandscapeScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) +int LandscapeScene::cellSize() const +{ + return m_cellSize; +} + +QGraphicsItem *LandscapeScene::createZoneItem(const LigoData &data) +{ + // 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 = new QGraphicsPixmapItem(pixmap->transformed(matrix, Qt::SmoothTransformation), 0, this); + } + else + { + // mirror image + QImage mirrorImage = pixmap->toImage(); + QPixmap mirrorPixmap = QPixmap::fromImage(mirrorImage.mirrored(true, false)); + item = new QGraphicsPixmapItem(mirrorPixmap.transformed(matrix, Qt::SmoothTransformation), 0, this); + } + // Enable bilinear filtering + item->setTransformationMode(Qt::SmoothTransformation); + + // Set position graphics item with offset for large piece + NLLIGO::CZoneBankElement *zoneBankItem = m_zoneBuilder->getZoneBank().getElementByZoneName(data.ZoneName); + item->setPos(data.PosX * m_cellSize, (abs(data.PosY) - zoneBankItem->getSizeY() + 1) * m_cellSize); + + // The size graphics item should be equal or proportional m_cellSize + item->setScale(m_cellSize / 256.0); + + // add debug info + QGraphicsSimpleTextItem *itemText = addSimpleText(QString("%1,%2 R-%3 F-%4"). + arg(data.PosX).arg(data.PosY). + arg(data.Rot * 90.0). + arg(data.Flip), + QFont("Helvetica [Cronyx]", 14)); + + itemText->setZValue(2); + itemText->setPos(data.PosX * m_cellSize + 10, (abs(data.PosY) - zoneBankItem->getSizeY() + 1) * m_cellSize + 10); + itemText->setBrush(QBrush(Qt::white)); + + return item; +} + +void LandscapeScene::processZoneRegion(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.empty()) && + (zoneName != STRING_UNUSED) && + (zoneRegion.getPosX(i, j) == 0) && + (zoneRegion.getPosY(i, j) == 0)) + { + LigoData data; + data.PosX = i; + data.PosY = j; + data.ZoneName = zoneName; + data.Rot = zoneRegion.getRot(i, j); + data.Flip = zoneRegion.getFlip(i, j); + QGraphicsItem *item = createZoneItem(data); + } + } + } +} + +void LandscapeScene::setCurrentZoneRegion(NLLIGO::CZoneRegion *zoneRegion) +{ + m_zoneRegion = zoneRegion; +} + +void LandscapeScene::snapshot(const QString &fileName, int sizeSource) +{ + if (m_zoneRegion == 0) + return; + + sint32 regionMinX = m_zoneRegion->getMinX(); + sint32 regionMaxX = m_zoneRegion->getMaxX(); + sint32 regionMinY = m_zoneRegion->getMinY(); + sint32 regionMaxY = m_zoneRegion->getMaxY(); + + int regionWidth = (regionMaxX - regionMinX + 1); + int regionHeight = (regionMaxY - regionMinY + 1); + + snapshot(fileName, regionWidth * sizeSource, regionHeight * sizeSource); +} + +void LandscapeScene::snapshot(const QString &fileName, int width, int height) { - if (mouseEvent->button() != Qt::LeftButton) + if (m_zoneRegion == 0) return; + sint32 regionMinX = m_zoneRegion->getMinX(); + sint32 regionMaxX = m_zoneRegion->getMaxX(); + sint32 regionMinY = m_zoneRegion->getMinY(); + sint32 regionMaxY = m_zoneRegion->getMaxY(); + + int regionWidth = (regionMaxX - regionMinX + 1); + int regionHeight = (regionMaxY - regionMinY + 1); + + QImage image(width, 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, width, height); + + render(&painter, QRectF(0, 0, width, height), + QRectF(regionMinX * m_cellSize, abs(regionMaxY) * m_cellSize, regionWidth * m_cellSize, regionHeight * m_cellSize)); + + image.save(fileName); + +} + +void LandscapeScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) +{ qreal x = mouseEvent->scenePos().rx(); qreal y = mouseEvent->scenePos().ry(); if ((x < 0) || (y < 0)) return; - LigoData ligoData = m_listZonesWidget->currentLigoData(); - if (ligoData.ZoneName == "") - return; + if (mouseEvent->button() == Qt::LeftButton) + { + // Add new zone brick + LigoData ligoData = m_listZonesWidget->currentLigoData(); + if (ligoData.ZoneName == "") + return; + + ligoData.PosX = int(floor(x / m_cellSize)); + ligoData.PosY = int(-floor(y / m_cellSize)); - ligoData.PosX = m_cellSize * int(x / m_cellSize);; - ligoData.PosY = m_cellSize * int(y / m_cellSize); - ligoData.Scale = m_cellSize / 256.0; + AddLigoTileCommand *action = new AddLigoTileCommand(ligoData, this); + m_undoStack->push(action); + } - LigoTileCommand *action = new LigoTileCommand(ligoData, m_zoneBuilder, this); - m_undoStack->push(action); + /*if (mouseEvent->button() == Qt::RightButton) + { + // Delete zone brick + LigoData ligoData; + ligoData.PosX = int(floor(x / m_cellSize)); + ligoData.PosY = int(floor(y / m_cellSize)); + ligoData.ZoneName = m_zoneRegion->getName(ligoData.PosX, -ligoData.PosY); + ligoData.Flip = m_zoneRegion->getFlip(ligoData.PosX, -ligoData.PosY); + ligoData.Rot = m_zoneRegion->getRot(ligoData.PosX, -ligoData.PosY); + DelLigoTileCommand *action = new DelLigoTileCommand(ligoData, this); + m_undoStack->push(action); + }*/ QGraphicsScene::mousePressEvent(mouseEvent); } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h index 80417d4ff..2af45bf4b 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h @@ -21,6 +21,7 @@ // Project includes // NeL includes +#include // Qt includes #include @@ -32,6 +33,34 @@ namespace LandscapeEditor class ZoneBuilder; class ListZonesWidget; +// Data +struct LigoData +{ + sint32 PosX; + sint32 PosY; + uint8 Rot; + uint8 Flip; + std::string ZoneName; + std::string SharingMatNames[4]; + uint8 SharingCutEdges[4]; + 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 LandscapeScene : public QGraphicsScene { Q_OBJECT @@ -40,6 +69,15 @@ public: LandscapeScene(QUndoStack *undoStack, ListZonesWidget *listZonesWidget, ZoneBuilder *zoneBuilder, QObject *parent = 0); virtual ~LandscapeScene(); + int cellSize() const; + + QGraphicsItem *createZoneItem(const LigoData &data); + void processZoneRegion(const NLLIGO::CZoneRegion &zoneRegion); + void setCurrentZoneRegion(NLLIGO::CZoneRegion *zoneRegion); + + void snapshot(const QString &fileName, int sizeSource); + void snapshot(const QString &fileName, int width, int height); + protected: virtual void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent); @@ -49,6 +87,7 @@ private: ListZonesWidget *m_listZonesWidget; QUndoStack *m_undoStack; ZoneBuilder *m_zoneBuilder; + NLLIGO::CZoneRegion *m_zoneRegion; }; } /* namespace LandscapeEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp index 26dd386ed..610028762 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp @@ -114,11 +114,11 @@ void LandscapeView::drawForeground(QPainter *painter, const QRectF &rect) return; qreal scaleFactor = transform().m11(); - painter->setPen(QPen(Qt::white, 1 / scaleFactor, Qt::SolidLine)); + painter->setPen(QPen(Qt::white, 0, Qt::SolidLine)); // draw grid - qreal left = m_cellSize * int(rect.left() / m_cellSize); - qreal top = m_cellSize * int(rect.top() / m_cellSize); + qreal left = m_cellSize * floor(rect.left() / m_cellSize); + qreal top = m_cellSize * floor(rect.top() / m_cellSize); // draw vertical lines while (left < rect.right()) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp index 56e362181..66d31479b 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp @@ -107,6 +107,9 @@ LigoData ListZonesWidget::currentLigoData() const QModelIndex index = m_ui.listView->currentIndex(); if (index.isValid()) ligoData.ZoneName = index.data().toString().toStdString(); + + ligoData.Rot = m_ui.rotComboBox->currentIndex(); + ligoData.Flip = m_ui.flipComboBox->currentIndex(); return ligoData; } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h index b1a6525fc..8ad5d4c25 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h @@ -21,6 +21,7 @@ // Project includes #include "ui_list_zones_widget.h" #include "builder_zone.h" +#include "landscape_scene.h" // NeL includes diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.ui index 289cb45dd..4d9f63129 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.ui +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.ui @@ -215,7 +215,7 @@ 3 - + 0° @@ -233,7 +233,7 @@ - 170° + 270° @@ -249,7 +249,7 @@ - + NoFlip @@ -273,14 +273,14 @@ - + Force - + Not propogate diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.ui index bb94fcc0d..8be20c9aa 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.ui +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.ui @@ -23,6 +23,9 @@ Data directory: + + pathLineEdit + @@ -40,6 +43,9 @@ Context: + + contextComboBox + @@ -68,8 +74,8 @@ accept() - 248 - 254 + 257 + 83 157 @@ -84,8 +90,8 @@ reject() - 316 - 260 + 325 + 83 286 diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/shapshot_dialog.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/shapshot_dialog.ui new file mode 100644 index 000000000..792d9f7a4 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/shapshot_dialog.ui @@ -0,0 +1,208 @@ + + + SnapshotDialog + + + + 0 + 0 + 286 + 182 + + + + Snapshot + + + + + + Original size + + + true + + + + + + + false + + + Custom size + + + + + + + false + + + + + + + + + 99999 + + + 512 + + + + + + + false + + + TextLabel + + + heightSpinBox + + + + + + + false + + + 99999 + + + 512 + + + + + + + TextLabel + + + widthSpinBox + + + + + + + Keep bitmap ratio + + + true + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + originalSizeRadioButton + customSizeRadioButton + widthSpinBox + heightSpinBox + keepRatioCheckBox + buttonBox + + + + + buttonBox + accepted() + SnapshotDialog + accept() + + + 227 + 164 + + + 157 + 158 + + + + + buttonBox + rejected() + SnapshotDialog + reject() + + + 276 + 170 + + + 285 + 158 + + + + + customSizeRadioButton + toggled(bool) + groupBox + setEnabled(bool) + + + 59 + 39 + + + 78 + 62 + + + + + keepRatioCheckBox + toggled(bool) + heightSpinBox + setDisabled(bool) + + + 84 + 122 + + + 178 + 106 + + + + + keepRatioCheckBox + toggled(bool) + label_2 + setDisabled(bool) + + + 55 + 129 + + + 48 + 103 + + + + + diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/snapshot_dialog.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/snapshot_dialog.cpp new file mode 100644 index 000000000..ff6ef1673 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/snapshot_dialog.cpp @@ -0,0 +1,45 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +// Project includes +#include "snapshot_dialog.h" +#include "landscape_editor_constants.h" + +#include "../core/icore.h" +#include "../core/core_constants.h" + +// NeL includes +#include + +// Qt includes +#include +#include + +namespace LandscapeEditor +{ + +SnapshotDialog::SnapshotDialog(QWidget *parent) + : QDialog(parent) +{ + m_ui.setupUi(this); +} + +SnapshotDialog::~SnapshotDialog() +{ +} + +} /* namespace LandscapeEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/snapshot_dialog.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/snapshot_dialog.h new file mode 100644 index 000000000..906d59498 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/snapshot_dialog.h @@ -0,0 +1,47 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +#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(); + +private Q_SLOTS: + + +private: + + Ui::SnapshotDialog m_ui; +}; /* class SnapshotDialog */ + +} /* namespace LandscapeEditor */ + +#endif // SNAPSHOT_DIALOG_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.cpp new file mode 100644 index 000000000..a3f109ada --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.cpp @@ -0,0 +1,119 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +// Project includes +#include "zone_region_editor.h" + +// NeL includes +#include +#include +#include +#include + +// Qt includes +#include + +namespace LandscapeEditor +{ + +ZoneRegionEditor::ZoneRegionEditor() +{ + m_fileName = ""; +} + +ZoneRegionEditor::~ZoneRegionEditor() +{ +} + +bool ZoneRegionEditor::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 ZoneRegionEditor::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; +} + +void ZoneRegionEditor::setFileName(const std::string &fileName) +{ + m_fileName = fileName; +} + +NLLIGO::CZoneRegion &ZoneRegionEditor::zoneRegion() +{ + return m_zoneRegion; +} + +} /* namespace LandscapeEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.h new file mode 100644 index 000000000..fd53d5483 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.h @@ -0,0 +1,62 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +#ifndef LANDSCAPE_EDITOR_H +#define LANDSCAPE_EDITOR_H + +// Project includes + +// NeL includes +#include +#include + +// STL includes +#include + +// Qt includes + +namespace LandscapeEditor +{ + +class ZoneRegionEditor +{ +public: + ZoneRegionEditor(); + ~ZoneRegionEditor(); + + // Load landscape data from file + bool load(const std::string &fileName); + + // Save landscape data to file + bool save(); + + // Set file name + void setFileName(const std::string &fileName); + + NLLIGO::CZoneRegion &zoneRegion(); + +private: + + bool m_modified; + bool m_editable; + std::string m_fileName; + NLLIGO::CZoneRegion m_zoneRegion; +}; + +} /* namespace LandscapeEditor */ + +#endif // LANDSCAPE_EDITOR_H From 7c98cba1f5821df24cdc4052a25b2c52b75f3650 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Tue, 28 Jun 2011 02:55:38 +0300 Subject: [PATCH 08/89] Changed: #1301 Binding 2d renderer to NELLIGO. --HG-- branch : gsoc2011-worldeditorqt --- .../plugins/landscape_editor/builder_zone.cpp | 256 +- .../plugins/landscape_editor/builder_zone.h | 77 +- .../landscape_editor/builder_zone_region.cpp | 2084 +++++++++++++++++ .../landscape_editor/builder_zone_region.h | 134 +- .../landscape_editor/landscape_actions.cpp | 103 +- .../landscape_editor/landscape_actions.h | 54 +- .../landscape_editor_window.cpp | 22 +- .../landscape_editor_window.h | 3 - .../landscape_editor/landscape_scene.cpp | 209 +- .../landscape_editor/landscape_scene.h | 45 +- .../landscape_editor/list_zones_widget.cpp | 32 +- .../landscape_editor/list_zones_widget.h | 9 +- .../landscape_editor/zone_region_editor.cpp | 66 + .../landscape_editor/zone_region_editor.h | 36 + 14 files changed, 2901 insertions(+), 229 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp index 288a4b1be..8271fe37c 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp @@ -17,6 +17,8 @@ // Project includes #include "builder_zone.h" +#include "list_zones_widget.h" +#include "landscape_actions.h" // NeL includes #include @@ -29,9 +31,9 @@ namespace LandscapeEditor { -const int PixmapScale = 256; PixmapDatabase::PixmapDatabase() + : m_textureSize(256) { } @@ -66,15 +68,21 @@ bool PixmapDatabase::loadPixmaps(const QString &zonePath, NLLIGO::CZoneBank &zon // Generate filled pixmap } // All pixmaps must be have same size - if (pixmap->width() != sizeX * PixmapScale) + if (pixmap->width() != sizeX * m_textureSize) { - QPixmap *scaledPixmap = new QPixmap(pixmap->scaled(sizeX * PixmapScale, sizeY * PixmapScale)); + 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); + delete progressDialog; return true; } @@ -105,8 +113,17 @@ QPixmap *PixmapDatabase::pixmap(const QString &zoneName) const return result; } -ZoneBuilder::ZoneBuilder() - : m_pixmapDatabase(0) +int PixmapDatabase::textureSize() const +{ + return m_textureSize; +} + +ZoneBuilder::ZoneBuilder(ListZonesWidget *listZonesWidget, LandscapeScene *landscapeScene, QUndoStack *undoStack) + : m_currentZoneRegion(-1), + m_pixmapDatabase(0), + m_listZonesWidget(listZonesWidget), + m_landscapeScene(landscapeScene), + m_undoStack(undoStack) { m_pixmapDatabase = new PixmapDatabase(); m_lastPathName = ""; @@ -144,10 +161,131 @@ bool ZoneBuilder::init(const QString &pathName, bool makeAZone) } } if ((makeAZone) && (bRet)) - newZone(); + createZoneRegion(); return bRet; } +void ZoneBuilder::actionLigoTile(const LigoData &data, const ZonePosition &zonePos) +{ + 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_undoStack->push(new LigoTileCommand(data, zonePos, this, m_landscapeScene)); +} + +void ZoneBuilder::actionLigoMove(uint index, sint32 deltaX, sint32 deltaY) +{ + nlinfo("ligoMove"); + //m_undoStack->push(new LigoMoveCommand(index, deltaX, deltaY, this)); +} + +void ZoneBuilder::actionLigoResize(uint index, sint32 newMinX, sint32 newMaxX, sint32 newMinY, sint32 newMaxY) +{ + 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) +{ + if (m_builderZoneRegions.empty()) + return; + + std::string zoneName = m_listZonesWidget->currentZoneName().toStdString(); + if (zoneName.empty()) + return; + + std::string error; + BuilderZoneRegion *builderZoneRegion = m_builderZoneRegions.at(m_currentZoneRegion); + builderZoneRegion->init(this, error); + + uint8 rot = uint8(m_listZonesWidget->currentRot()); + uint8 flip = uint8(m_listZonesWidget->currentFlip()); + + NLLIGO::CZoneBankElement *zoneBankElement = getZoneBank().getElementByZoneName(zoneName); + + m_undoStack->beginMacro(QString("Add zone %1,%2").arg(posX).arg(posY)); + 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); + } + m_undoStack->endMacro(); +} + +void ZoneBuilder::addTransition(const sint32 posX, const sint32 posY) +{ +} + +void ZoneBuilder::delZone(const sint32 posX, const sint32 posY) +{ + if (m_builderZoneRegions.empty()) + return; + + m_undoStack->beginMacro(QString("Del zone %1,%2").arg(posX).arg(posY)); + BuilderZoneRegion *builderZoneRegion = m_builderZoneRegions.at(m_currentZoneRegion); + std::string error; + builderZoneRegion->init(this, error); + builderZoneRegion->del(posX, posY); + m_undoStack->endMacro(); +} + +int ZoneBuilder::createZoneRegion() +{ + ZoneRegionEditor *newZoneRegion = new ZoneRegionEditor(); + m_zoneRegions.push_back(newZoneRegion); + if (m_currentZoneRegion == -1) + m_currentZoneRegion = m_zoneRegions.indexOf(newZoneRegion); + + newZone(); + return m_zoneRegions.indexOf(newZoneRegion); +} + +void ZoneBuilder::deleteZoneRegion(int id) +{ + if ((0 <= id) && (id < m_zoneRegions.size())) + delete m_zoneRegions.takeAt(id); +} + +void ZoneBuilder::setCurrentZoneRegion(int id) +{ + if ((0 <= id) && (id < m_zoneRegions.size())) + m_currentZoneRegion = id; +} + +int ZoneBuilder::currentIdZoneRegion() const +{ + return m_currentZoneRegion; +} + +ZoneRegionEditor *ZoneBuilder::currentZoneRegion() const +{ + return m_zoneRegions.at(m_currentZoneRegion); +} + +int ZoneBuilder::countZoneRegion() const +{ + return m_zoneRegions.size(); +} + +ZoneRegionEditor *ZoneBuilder::zoneRegion(int id) const +{ + return m_zoneRegions.at(id); +} + +void ZoneBuilder::ligoData(LigoData &data, const ZonePosition &zonePos) +{ + m_zoneRegions.at(zonePos.region)->ligoData(data, zonePos.x, zonePos.y); +} + +void ZoneBuilder::setLigoData(LigoData &data, const ZonePosition &zonePos) +{ + m_zoneRegions.at(zonePos.region)->setLigoData(data, zonePos.x, zonePos.y); +} + bool ZoneBuilder::initZoneBank (const QString &pathName) { QDir *dir = new QDir(pathName); @@ -178,8 +316,112 @@ QString ZoneBuilder::dataPath() const return m_lastPathName; } -void ZoneBuilder::newZone (bool bDisplay) +void ZoneBuilder::newZone() { + BuilderZoneRegion *builderZoneRegion = new BuilderZoneRegion(m_builderZoneRegions.size()); + m_builderZoneRegions.push_back(builderZoneRegion); + + // Select starting point for the moment 0,0 + sint32 x = 0, y = 0; + + // If there are some zone already present increase x until free + for (int i = 0; i < m_zoneRegions.size(); ++i) + { + const NLLIGO::CZoneRegion &zoneRegion = m_zoneRegions.at(i)->zoneRegion(); + const std::string &zoneName = zoneRegion.getName (x, y); + if ((zoneName != STRING_OUT_OF_BOUND) && (zoneName != STRING_UNUSED)) + { + ++x; + i = -1; + } + } + calcMask(); +} + +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 i; + sint32 x, y; + + m_minY = m_minX = 1000000; + m_maxY = m_maxX = -1000000; + + if (m_builderZoneRegions.size() == 0) + return; + + for (i = 0; i < (sint32)m_builderZoneRegions.size(); ++i) + { + const NLLIGO::CZoneRegion ®ion = zoneRegion(i)->zoneRegion(); + + 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; + + for (i = 0; i < (sint32)m_builderZoneRegions.size(); ++i) + if (i != m_currentZoneRegion) + { + const NLLIGO::CZoneRegion ®ion = zoneRegion(i)->zoneRegion(); + + 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) +{ + Q_FOREACH(ZoneRegionEditor *zoneRegion, m_zoneRegions) + { + const NLLIGO::CZoneRegion ®ion = zoneRegion->zoneRegion(); + if ((x < region.getMinX()) || (x > region.getMaxX()) || + (y < region.getMinY()) || (y > region.getMaxY())) + continue; + if (region.getName(x, y) != STRING_UNUSED) + { + int index = m_zoneRegions.indexOf(zoneRegion); + builderZoneRegionFrom = m_builderZoneRegions.at(index); + zonePos = ZonePosition(x, y, index); + return true; + } + } + + // The zone is not present in other region so it is an empty or oob zone of the current region + const NLLIGO::CZoneRegion ®ion = zoneRegion(builderZoneRegionFrom->getRegionId())->zoneRegion(); + 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; } } /* namespace LandscapeEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h index f43bb7d7e..54cdb3b73 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h @@ -19,9 +19,12 @@ #define BUILDER_ZONE_H // Project includes +#include "builder_zone_region.h" +#include "zone_region_editor.h" // NeL includes #include +#include // STL includes #include @@ -30,11 +33,38 @@ // Qt includes #include #include +#include #include #include +#include namespace LandscapeEditor { +class ListZonesWidget; +class LandscapeScene; + +// 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 PixmapDatabase @@ -59,8 +89,12 @@ public: /// 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; QMap m_pixmapMap; }; @@ -74,13 +108,37 @@ PixmapDatabase contains the graphics for the zones class ZoneBuilder { public: - ZoneBuilder(); + ZoneBuilder(ListZonesWidget *listZonesWidget, LandscapeScene *landscapeScene, QUndoStack *undoStack); ~ZoneBuilder(); - // Init zoneBank and init zone pixmap database + /// Init zoneBank and init zone pixmap database bool init(const QString &pathName, bool bMakeAZone); - void newZone(bool bDisplay=true); + void calcMask(); + void newZone(); + 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(sint32 posX, sint32 posY); + void addTransition(const sint32 posX, const sint32 posY); + void delZone(const sint32 posX, const sint32 posY); + + // Zone Region + int createZoneRegion(); + void deleteZoneRegion(int id); + void setCurrentZoneRegion(int id); + int currentIdZoneRegion() const; + ZoneRegionEditor *currentZoneRegion() const; + int countZoneRegion() const; + ZoneRegionEditor *zoneRegion(int id) const; + void ligoData(LigoData &data, const ZonePosition &zonePos); + void setLigoData(LigoData &data, const ZonePosition &zonePos); // Accessors NLLIGO::CZoneBank &getZoneBank() @@ -94,15 +152,24 @@ public: private: - // Scan ./zoneligos dir and add all *.ligozone files to zoneBank + /// Scan ./zoneligos dir and add all *.ligozone files to zoneBank bool initZoneBank (const QString &path); sint32 m_minX, m_maxX, m_minY, m_maxY; + std::vector m_zoneMask; + QString m_lastPathName; + QList m_zoneRegions; + int m_currentZoneRegion; + + std::vector m_builderZoneRegions; + PixmapDatabase *m_pixmapDatabase; NLLIGO::CZoneBank m_zoneBank; - std::vector m_currentSelection; + ListZonesWidget *m_listZonesWidget; + LandscapeScene *m_landscapeScene; + QUndoStack *m_undoStack; }; } /* namespace LandscapeEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.cpp index 4dbd3e9e1..2a4fc204a 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.cpp @@ -17,6 +17,8 @@ // Project includes #include "builder_zone_region.h" +#include "builder_zone.h" +#include "zone_region_editor.h" // NeL includes #include @@ -25,4 +27,2086 @@ namespace LandscapeEditor { + +BuilderZoneRegion::BuilderZoneRegion(uint regionId) + : m_regionId(regionId), + m_zoneBuilder(0), + m_firstInit(false) +{ +} + +bool BuilderZoneRegion::init(ZoneBuilder *zoneBuilder, std::string &error) +{ + if (m_firstInit) + return true; + + m_zoneBuilder = zoneBuilder; + + uint32 j, k; + SMatNode mn; + std::vector AllValues; + + // Build the material tree + m_zoneBuilder->getZoneBank().getCategoryValues("material", AllValues); + for (uint32 i = 0; i < AllValues.size(); ++i) + { + mn.Name = AllValues[i]; + m_matTree.push_back(mn); + } + + // Link between materials + AllValues.clear (); + m_zoneBuilder->getZoneBank().getCategoryValues("transname", AllValues); + for (uint32 i = 0; i < AllValues.size(); ++i) + { + // Get the 2 materials linked together + std::string matAstr, matBstr; + for (j = 0; j < AllValues[i].size(); ++j) + { + if (AllValues[i][j] == '-') + break; + else + matAstr += AllValues[i][j]; + } + ++j; + for (; j < AllValues[i].size(); ++j) + matBstr += AllValues[i][j]; + + // Find matA + for (j = 0; j < m_matTree.size(); ++j) + if (m_matTree[j].Name == matAstr) + break; + + if (j < m_matTree.size()) + { + // Find matB + for (k = 0; k < m_matTree.size(); ++k) + if (m_matTree[k].Name == matBstr) + break; + + if (k < m_matTree.size()) + { + // Add a ref to matB in node matA + m_matTree[j].Arcs.push_back(k); + + // Add a ref to matA in node matB + m_matTree[k].Arcs.push_back(j); + } + } + } + + m_firstInit = true; + return true; +} + +class ToUpdate +{ + struct SElement + { + sint32 x, y; + + // Material put into the cell to update + std::string matPut; + + BuilderZoneRegion *builderZoneRegion; + }; + + std::vector m_elements; + +public: + + void add(BuilderZoneRegion *builderZoneRegion, sint32 x, sint32 y, const std::string &matName) + { + bool bFound = false; + for (uint32 m = 0; m < m_elements.size(); ++m) + if ((m_elements[m].x == x) && (m_elements[m].y == y)) + { + bFound = true; + break; + } + if (!bFound) + { + SElement newElement; + newElement.x = x; + newElement.y = y; + newElement.matPut = matName; + newElement.builderZoneRegion = builderZoneRegion; + m_elements.push_back (newElement); + } + } + + void del(sint32 x, sint32 y) + { + bool bFound = false; + uint32 m; + for (m = 0; m < m_elements.size(); ++m) + if ((m_elements[m].x == x) && (m_elements[m].y == y)) + { + bFound = true; + break; + } + if (bFound) + { + for (; m < m_elements.size() - 1; ++m) + m_elements[m] = m_elements[m + 1]; + m_elements.resize (m_elements.size() - 1); + } + } + + uint32 size() + { + return m_elements.size(); + } + + sint32 getX(uint32 m) + { + return m_elements[m].x; + } + + sint32 getY(uint32 m) + { + return m_elements[m].y; + } + + BuilderZoneRegion* getBuilderZoneRegion(uint32 m) + { + return m_elements[m].builderZoneRegion; + } + + const std::string& getMat (uint32 m) + { + return m_elements[m].matPut; + } +}; + +void BuilderZoneRegion::add(sint32 x, sint32 y, uint8 rot, uint8 flip, NLLIGO::CZoneBankElement *zoneBankElement) +{ + sint32 sizeX = zoneBankElement->getSizeX(), sizeY = zoneBankElement->getSizeY(); + sint32 i, j; + NLLIGO::SPiece sMask, sPosX, sPosY; + ToUpdate tUpdate; // Transition to update + + if (!m_zoneBuilder->getZoneMask (x,y)) + return; + + if (zoneBankElement->getCategory("transname") != STRING_NO_CAT_TYPE) + { + addTransition (x, y, rot, flip, zoneBankElement); + return; + } + + // Create the mask in the good rotation and flip + sMask.Tab.resize(sizeX * sizeY); + sPosX.Tab.resize(sizeX * sizeY); + sPosY.Tab.resize(sizeX * sizeY); + + for(j = 0; j < sizeY; ++j) + for(i = 0; i < sizeX; ++i) + { + sPosX.Tab[i + j * sizeX] = (uint8)i; + sPosY.Tab[i + j * sizeX] = (uint8)j; + sMask.Tab[i + j * sizeX] = zoneBankElement->getMask()[i + j * sizeX]; + } + sPosX.w = sPosY.w = sMask.w = sizeX; + sPosX.h = sPosY.h = sMask.h = sizeY; + sMask.rotFlip(rot, flip); + sPosX.rotFlip(rot, flip); + sPosY.rotFlip(rot, flip); + + // Test if the pieces can be put (due to mask) + for (j = 0; j < sMask.h; ++j) + for (i = 0; i < sMask.w; ++i) + if (sMask.Tab[i + j * sMask.w]) + { + if (m_zoneBuilder->getZoneMask(x + i, y + j) == false) + return; + } + + // Delete all pieces that are under the mask + for (j = 0; j < sMask.h; ++j) + for (i = 0; i < sMask.w; ++i) + if (sMask.Tab[i + j * sMask.w]) + { + del(x + i, y + j, true, &tUpdate); + } + + // Delete all around all material that are not from the same as us + const std::string &curMat = zoneBankElement->getCategory ("material"); + + if (curMat != STRING_NO_CAT_TYPE) + { + // This element is a valid material + // Place the piece + const std::string &eltName = zoneBankElement->getName (); + for (j = 0; j < sMask.h; ++j) + for (i = 0; i < sMask.w; ++i) + if (sMask.Tab[i + j * sMask.w]) + { + set(x + i, y + j, sPosX.Tab[i + j * sPosX.w], sPosY.Tab[i + j * sPosY.w], eltName); + setRot(x + i, y + j, rot); + setFlip(x + i, y + j, flip); + } + + // Put all transitions between different materials + putTransitions (x, y, sMask, curMat, &tUpdate); + + // Place the piece + for (j = 0; j < sMask.h; ++j) + for (i = 0; i < sMask.w; ++i) + if (sMask.Tab[i + j * sMask.w]) + { + set(x + i, y + j, sPosX.Tab[i + j * sPosX.w], sPosY.Tab[i + j * sPosY.w], eltName); + setRot(x + i, y + j, rot); + setFlip(x + i, y + j, flip); + } + } +} + +void BuilderZoneRegion::invertCutEdge(sint32 x, sint32 y, uint8 cePos) +{ + const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion(); + if ((x < zoneRegion.getMinX ()) || (x > zoneRegion.getMaxX ()) || + (y < zoneRegion.getMinY ()) || (y > zoneRegion.getMaxY ())) + return; + + NLLIGO::CZoneBankElement *zoneBankElement = m_zoneBuilder->getZoneBank().getElementByZoneName(zoneRegion.getName(x, y)); + if (zoneBankElement == NULL) + return; + if (zoneBankElement->getCategory("transname") == STRING_NO_CAT_TYPE) + return; + + + ZonePosition zonePos(x, y, m_regionId); + LigoData dataZone; + + m_zoneBuilder->ligoData(dataZone, zonePos); + if (dataZone.sharingCutEdges[cePos] != 3 - dataZone.sharingCutEdges[cePos]) + { + dataZone.sharingCutEdges[cePos] = 3 - dataZone.sharingCutEdges[cePos]; + + m_zoneBuilder->actionLigoTile(dataZone, zonePos); + } + updateTrans(x, y); + + // If the transition number is not the same propagate the change + // Propagate where the edge is cut (1/3 or 2/3) and update the transition + if (cePos == 2) + if (dataZone.sharingMatNames[0] != dataZone.sharingMatNames[2]) + { + if (x > zoneRegion.getMinX ()) + { + // [x-1][y].right = [x][y].left + // _Zones[(x-1-zoneRegion->getMinX ())+(y-zoneRegion->getMinY ())*stride].SharingCutEdges[3] = dataZonePos.SharingCutEdges[2]; + ZonePosition zonePosTemp(x - 1, y, m_regionId); + LigoData dataZoneTemp; + m_zoneBuilder->ligoData(dataZoneTemp, zonePosTemp); + if (dataZoneTemp.sharingCutEdges[3] != dataZone.sharingCutEdges[2]) + { + dataZoneTemp.sharingCutEdges[3] = dataZone.sharingCutEdges[2]; + + // Add modification landscape + m_zoneBuilder->actionLigoTile(dataZoneTemp, zonePosTemp); + } + } + updateTrans (x - 1, y); + } + if (cePos == 3) + if (dataZone.sharingMatNames[1] != dataZone.sharingMatNames[3]) + { + if (x < zoneRegion.getMaxX ()) + { + // [x+1][y].left = [x][y].right + ZonePosition zonePosTemp(x + 1, y, m_regionId); + LigoData dataZoneTemp; + m_zoneBuilder->ligoData(dataZoneTemp, zonePosTemp); + if (dataZoneTemp.sharingCutEdges[2] != dataZone.sharingCutEdges[3]) + { + dataZoneTemp.sharingCutEdges[2] = dataZone.sharingCutEdges[3]; + + // Add modification landscape + m_zoneBuilder->actionLigoTile(dataZoneTemp, zonePosTemp); + } + } + updateTrans (x + 1, y); + } + if (cePos == 1) + if (dataZone.sharingMatNames[0] != dataZone.sharingMatNames[1]) + { + if (y > zoneRegion.getMinY ()) + { + // [x][y-1].up = [x][y].down + ZonePosition zonePosTemp(x, y - 1, m_regionId); + LigoData dataZoneTemp; + m_zoneBuilder->ligoData(dataZoneTemp, zonePosTemp); + if (dataZoneTemp.sharingCutEdges[0] != dataZone.sharingCutEdges[1]) + { + dataZoneTemp.sharingCutEdges[0] = dataZone.sharingCutEdges[1]; + + // Add modification landscape + m_zoneBuilder->actionLigoTile(dataZoneTemp, zonePosTemp); + } + } + updateTrans (x, y-1); + } + if (cePos == 0) + if (dataZone.sharingMatNames[2] != dataZone.sharingMatNames[3]) + { + if (y < zoneRegion.getMaxY ()) + { + // [x][y+1].down = [x][y].up + ZonePosition zonePosTemp(x, y + 1, m_regionId); + LigoData dataZoneTemp; + m_zoneBuilder->ligoData(dataZoneTemp, zonePosTemp); + if (dataZoneTemp.sharingCutEdges[1] != dataZone.sharingCutEdges[0]) + { + dataZoneTemp.sharingCutEdges[1] = dataZone.sharingCutEdges[0]; + + // Add modification landscape + m_zoneBuilder->actionLigoTile(dataZoneTemp, zonePosTemp); + } + } + updateTrans (x, y + 1); + } +} + +void BuilderZoneRegion::cycleTransition(sint32 x, sint32 y) +{ + const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion(); + if ((x < zoneRegion.getMinX ()) || (x > zoneRegion.getMaxX ()) || + (y < zoneRegion.getMinY ()) || (y > zoneRegion.getMaxY ())) + return; + + NLLIGO::CZoneBankElement *zoneBankElement = m_zoneBuilder->getZoneBank().getElementByZoneName (zoneRegion.getName (x, y)); + if (zoneBankElement == NULL) + return; + if (zoneBankElement->getCategory("transname") == STRING_NO_CAT_TYPE) + return; + + // \todo trap -> choose the good transition in function of the transition under the current location + // Choose the next possible transition if not the same as the first one + // Choose among all transition of the same number + + updateTrans (x, y); +} + +bool BuilderZoneRegion::addNotPropagate (sint32 x, sint32 y, uint8 rot, uint8 flip, NLLIGO::CZoneBankElement *zoneBankElement) +{ + const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion(); + sint32 sizeX = zoneBankElement->getSizeX(), sizeY = zoneBankElement->getSizeY(); + sint32 i, j; + NLLIGO::SPiece sMask, sPosX, sPosY; + ToUpdate tUpdate; // Transition to update + + if (!m_zoneBuilder->getZoneMask (x, y)) + return false; + + if (zoneBankElement->getCategory("transname") != STRING_NO_CAT_TYPE) + { + addTransition (x, y, rot, flip, zoneBankElement); + return true; + } + + // Create the mask in the good rotation and flip + sMask.Tab.resize (sizeX * sizeY); + sPosX.Tab.resize (sizeX * sizeY); + sPosY.Tab.resize (sizeX * sizeY); + + for (j = 0; j < sizeY; ++j) + for (i = 0; i < sizeX; ++i) + { + sPosX.Tab[i + j * sizeX] = (uint8)i; + sPosY.Tab[i + j * sizeX] = (uint8)j; + sMask.Tab[i + j * sizeX] = zoneBankElement->getMask()[i + j * sizeX]; + } + sPosX.w = sPosY.w = sMask.w = sizeX; + sPosX.h = sPosY.h = sMask.h = sizeY; + sMask.rotFlip (rot, flip); + sPosX.rotFlip (rot, flip); + sPosY.rotFlip (rot, flip); + + // Test if the pieces can be put (due to mask) + sint32 stride = (1 + zoneRegion.getMaxX () - zoneRegion.getMinX ()); + for (j = 0; j < sMask.h; ++j) + for (i = 0; i < sMask.w; ++i) + if (sMask.Tab[i+j*sMask.w]) + { + if (m_zoneBuilder->getZoneMask(x + i, y + j) == false) + return false; + if (((x + i) < zoneRegion.getMinX ()) || ((x + i) > zoneRegion.getMaxX ()) || + ((y + j) < zoneRegion.getMinY ()) || ((y + j) > zoneRegion.getMaxY ())) + return false; + NLLIGO::CZoneBankElement *zoneBankElementUnder = m_zoneBuilder->getZoneBank().getElementByZoneName(zoneRegion.getName (x + i, y + j)); + if (zoneBankElementUnder == NULL) + return false; + if (zoneBankElementUnder->getCategory("material") != zoneBankElement->getCategory("material")) + return false; + } + + // Delete all pieces that are under the mask + for (j = 0; j < sMask.h; ++j) + for (i = 0; i < sMask.w; ++i) + if (sMask.Tab[i + j * sMask.w]) + { + del(x + i, y + j, true, &tUpdate); + } + + const std::string &curMat = zoneBankElement->getCategory ("material"); + + if (curMat != STRING_NO_CAT_TYPE) + { + // This element is a valid material + // Place the piece + const std::string &EltName = zoneBankElement->getName (); + for (j = 0; j < sMask.h; ++j) + for (i = 0; i < sMask.w; ++i) + if (sMask.Tab[i + j * sMask.w]) + { + set (x + i, y + j, sPosX.Tab[i + j * sPosX.w], sPosY.Tab[i + j * sPosY.w], EltName); + setRot (x + i, y + j, rot); + setFlip (x + i, y + j, flip); + } + } + + return true; +} + +void BuilderZoneRegion::addForce (sint32 x, sint32 y, uint8 rot, uint8 flip, NLLIGO::CZoneBankElement *zoneBankElement) +{ + const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion(); + sint32 sizeX = zoneBankElement->getSizeX(), sizeY = zoneBankElement->getSizeY(); + sint32 i, j; + NLLIGO::SPiece sMask, sPosX, sPosY; + ToUpdate tUpdate; // Transition to update + + if (!m_zoneBuilder->getZoneMask (x, y)) + return; + + /* + if (pElt->getCategory("transname") != STRING_NO_CAT_TYPE) + { + addTransition (x, y, nRot, nFlip, pElt); + return; + }*/ + + // Create the mask in the good rotation and flip + sMask.Tab.resize (sizeX * sizeY); + sPosX.Tab.resize (sizeX * sizeY); + sPosY.Tab.resize (sizeX * sizeY); + + for (j = 0; j < sizeY; ++j) + for (i = 0; i < sizeX; ++i) + { + sPosX.Tab[i + j * sizeX] = (uint8)i; + sPosY.Tab[i + j * sizeX] = (uint8)j; + sMask.Tab[i + j * sizeX] = zoneBankElement->getMask()[i + j * sizeX]; + } + sPosX.w = sPosY.w = sMask.w = sizeX; + sPosX.h = sPosY.h = sMask.h = sizeY; + sMask.rotFlip (rot, flip); + sPosX.rotFlip (rot, flip); + sPosY.rotFlip (rot, flip); + + // Test if the pieces can be put (due to mask) + // All space under the mask must be empty + sint32 stride = (1 + zoneRegion.getMaxX () - zoneRegion.getMinX ()); + for (j = 0; j < sMask.h; ++j) + for (i = 0; i < sMask.w; ++i) + if (sMask.Tab[i+j*sMask.w]) + { + if (m_zoneBuilder->getZoneMask(x+i, y+j) == false) + return; + if (((x+i) < zoneRegion.getMinX ()) || ((x+i) > zoneRegion.getMaxX ()) || + ((y+j) < zoneRegion.getMinY ()) || ((y+j) > zoneRegion.getMaxY ())) + return; + NLLIGO::CZoneBankElement *zoneBankElementUnder = m_zoneBuilder->getZoneBank().getElementByZoneName(zoneRegion.getName (x + i, y + i)); + if (zoneBankElementUnder != NULL) + return; + } + + // Delete all pieces that are under the mask + for (j = 0; j < sMask.h; ++j) + for (i = 0; i < sMask.w; ++i) + if (sMask.Tab[i+j*sMask.w]) + { + del(x+i, y+j, true, &tUpdate); + } + + const std::string &curMat = zoneBankElement->getCategory ("material"); + const bool transition = zoneBankElement->getCategory("transname") != STRING_NO_CAT_TYPE; + + if (curMat != STRING_NO_CAT_TYPE || transition) + { + // This element is a valid material + // Place the piece + const std::string &eltName = zoneBankElement->getName(); + for (j = 0; j < sMask.h; ++j) + for (i = 0; i < sMask.w; ++i) + if (sMask.Tab[i + j * sMask.w]) + { + set(x + i, y + j, sPosX.Tab[i + j * sPosX.w], sPosY.Tab[i + j * sPosY.w], eltName, transition); + setRot(x + i, y + j, rot); + setFlip(x + i, y + j, flip); + } + } +} + +uint8 TransToEdge[72][4] = +{ + { 0, 0, 1, 1 }, // TransNum = 0, Flip = 0, Rot = 0 + { 2, 2, 0, 0 }, // TransNum = 0, Flip = 0, Rot = 1 + { 0, 0, 2, 2 }, // TransNum = 0, Flip = 0, Rot = 2 + { 1, 1, 0, 0 }, // TransNum = 0, Flip = 0, Rot = 3 + { 0, 0, 1, 1 }, // TransNum = 0, Flip = 1, Rot = 0 + { 2, 2, 0, 0 }, // TransNum = 0, Flip = 1, Rot = 1 + { 0, 0, 2, 2 }, // TransNum = 0, Flip = 1, Rot = 2 + { 1, 1, 0, 0 }, // TransNum = 0, Flip = 1, Rot = 3 + + { 0, 0, 1, 2 }, // TransNum = 1, Flip = 0, Rot = 0 + { 1, 2, 0, 0 }, // TransNum = 1, Flip = 0, Rot = 1 + { 0, 0, 1, 2 }, // TransNum = 1, Flip = 0, Rot = 2 + { 1, 2, 0, 0 }, // TransNum = 1, Flip = 0, Rot = 3 + { 0, 0, 2, 1 }, // TransNum = 1, Flip = 1, Rot = 0 + { 2, 1, 0, 0 }, // TransNum = 1, Flip = 1, Rot = 1 + { 0, 0, 2, 1 }, // TransNum = 1, Flip = 1, Rot = 2 + { 2, 1, 0, 0 }, // TransNum = 1, Flip = 1, Rot = 3 + + { 0, 0, 2, 2 }, // TransNum = 2, Flip = 0, Rot = 0 + { 1, 1, 0, 0 }, // TransNum = 2, Flip = 0, Rot = 1 + { 0, 0, 1, 1 }, // TransNum = 2, Flip = 0, Rot = 2 + { 2, 2, 0, 0 }, // TransNum = 2, Flip = 0, Rot = 3 + { 0, 0, 2, 2 }, // TransNum = 2, Flip = 1, Rot = 0 + { 1, 1, 0, 0 }, // TransNum = 2, Flip = 1, Rot = 1 + { 0, 0, 1, 1 }, // TransNum = 2, Flip = 1, Rot = 2 + { 2, 2, 0, 0 }, // TransNum = 2, Flip = 1, Rot = 3 + + { 0, 1, 1, 0 }, // TransNum = 3, Flip = 0, Rot = 0 + { 0, 2, 0, 1 }, // TransNum = 3, Flip = 0, Rot = 1 + { 2, 0, 0, 2 }, // TransNum = 3, Flip = 0, Rot = 2 + { 1, 0, 2, 0 }, // TransNum = 3, Flip = 0, Rot = 3 + { 0, 2, 0, 1 }, // TransNum = 3, Flip = 1, Rot = 0 + { 2, 0, 0, 2 }, // TransNum = 3, Flip = 1, Rot = 1 + { 1, 0, 2, 0 }, // TransNum = 3, Flip = 1, Rot = 2 + { 0, 1, 1, 0 }, // TransNum = 3, Flip = 1, Rot = 3 + + { 0, 2, 1, 0 }, // TransNum = 4, Flip = 0, Rot = 0 + { 0, 2, 0, 2 }, // TransNum = 4, Flip = 0, Rot = 1 + { 1, 0, 0, 2 }, // TransNum = 4, Flip = 0, Rot = 2 + { 1, 0, 1, 0 }, // TransNum = 4, Flip = 0, Rot = 3 + { 0, 1, 0, 1 }, // TransNum = 4, Flip = 1, Rot = 0 + { 2, 0, 0, 1 }, // TransNum = 4, Flip = 1, Rot = 1 + { 2, 0, 2, 0 }, // TransNum = 4, Flip = 1, Rot = 2 + { 0, 1, 2, 0 }, // TransNum = 4, Flip = 1, Rot = 3 + + { 0, 2, 2, 0 }, // TransNum = 5, Flip = 0, Rot = 0 + { 0, 1, 0, 2 }, // TransNum = 5, Flip = 0, Rot = 1 + { 1, 0, 0, 1 }, // TransNum = 5, Flip = 0, Rot = 2 + { 2, 0, 1, 0 }, // TransNum = 5, Flip = 0, Rot = 3 + { 0, 1, 0, 2 }, // TransNum = 5, Flip = 1, Rot = 0 + { 1, 0, 0, 1 }, // TransNum = 5, Flip = 1, Rot = 1 + { 2, 0, 1, 0 }, // TransNum = 5, Flip = 1, Rot = 2 + { 0, 2, 2, 0 }, // TransNum = 5, Flip = 1, Rot = 3 + + { 0, 1, 1, 0 }, // TransNum = 6, Flip = 0, Rot = 0 + { 0, 2, 0, 1 }, // TransNum = 6, Flip = 0, Rot = 1 + { 2, 0, 0, 2 }, // TransNum = 6, Flip = 0, Rot = 2 + { 1, 0, 2, 0 }, // TransNum = 6, Flip = 0, Rot = 3 + { 0, 2, 0, 1 }, // TransNum = 6, Flip = 1, Rot = 0 + { 2, 0, 0, 2 }, // TransNum = 6, Flip = 1, Rot = 1 + { 1, 0, 2, 0 }, // TransNum = 6, Flip = 1, Rot = 2 + { 0, 1, 1, 0 }, // TransNum = 6, Flip = 1, Rot = 3 + + { 0, 2, 1, 0 }, // TransNum = 7, Flip = 0, Rot = 0 + { 0, 2, 0, 2 }, // TransNum = 7, Flip = 0, Rot = 1 + { 1, 0, 0, 2 }, // TransNum = 7, Flip = 0, Rot = 2 + { 1, 0, 1, 0 }, // TransNum = 7, Flip = 0, Rot = 3 + { 0, 1, 0, 1 }, // TransNum = 7, Flip = 1, Rot = 0 + { 2, 0, 0, 1 }, // TransNum = 7, Flip = 1, Rot = 1 + { 2, 0, 2, 0 }, // TransNum = 7, Flip = 1, Rot = 2 + { 0, 1, 2, 0 }, // TransNum = 7, Flip = 1, Rot = 3 + + { 0, 2, 2, 0 }, // TransNum = 8, Flip = 0, Rot = 0 + { 0, 1, 0, 2 }, // TransNum = 8, Flip = 0, Rot = 1 + { 1, 0, 0, 1 }, // TransNum = 8, Flip = 0, Rot = 2 + { 2, 0, 1, 0 }, // TransNum = 8, Flip = 0, Rot = 3 + { 0, 1, 0, 2 }, // TransNum = 8, Flip = 1, Rot = 0 + { 1, 0, 0, 1 }, // TransNum = 8, Flip = 1, Rot = 1 + { 2, 0, 1, 0 }, // TransNum = 8, Flip = 1, Rot = 2 + { 0, 2, 2, 0 }, // TransNum = 8, Flip = 1, Rot = 3 +}; + +void BuilderZoneRegion::addTransition (sint32 x, sint32 y, uint8 rot, uint8 flip, NLLIGO::CZoneBankElement *zoneBankElement) +{ + const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion(); + uint32 i; + // Check that we write in an already defined place + if ((x < zoneRegion.getMinX ()) || (x > zoneRegion.getMaxX ()) || + (y < zoneRegion.getMinY ()) || (y > zoneRegion.getMaxY ())) + return; + + // Check size + if ((zoneBankElement->getSizeX() != 1) || (zoneBankElement->getSizeY() != 1)) + return; + + // Check that an element already exist at position we want put the transition + NLLIGO::CZoneBankElement *zoneBankElementUnder = m_zoneBuilder->getZoneBank().getElementByZoneName(zoneRegion.getName(x, y)); + if (zoneBankElementUnder == NULL) + return; + + // And check that this element is also a transition and the same transition + if (zoneBankElementUnder->getCategory ("transname") == STRING_NO_CAT_TYPE) + return; + if (zoneBankElementUnder->getCategory ("transname") != zoneBankElement->getCategory("transname")) + return; + + std::string underType = zoneBankElementUnder->getCategory("transtype"); + std::string overType = zoneBankElement->getCategory("transtype"); + std::string underNum = zoneBankElementUnder->getCategory("transnum"); + std::string overNum = zoneBankElement ->getCategory("transnum"); + + ZonePosition zonePosTemp(x, y, m_regionId); + LigoData dataZoneTemp; + m_zoneBuilder->ligoData(dataZoneTemp, zonePosTemp); + LigoData dataZoneOriginal = dataZoneTemp; + + bool bMustPropagate = false; + // Same type of transition ? + if (zoneBankElementUnder->getCategory("transtype") != zoneBankElement->getCategory("transtype")) + { + // No so random the cutEdges + for (i = 0; i < 4; ++i) + { + uint8 nCut = (uint8)(1.0f + NLMISC::frand(2.0f)); + NLMISC::clamp(nCut, (uint8)1, (uint8)2); + + dataZoneTemp.sharingCutEdges[i] = nCut; + } + zoneBankElement = NULL; + bMustPropagate = true; + } + else + { + // Put exactly the transition as given + sint32 transnum = atoi(zoneBankElement->getCategory("transnum").c_str()); + sint32 flip = zoneRegion.getFlip(x, y); + sint32 rot = zoneRegion.getRot(x, y); + sint32 pos1 = -1, pos2 = -1; + + for (i = 0; i < 4; ++i) + { + if ((TransToEdge[transnum * 8 + flip * 4 + rot][i] != 0) && + (TransToEdge[transnum * 8 + flip * 4 + rot][i] != dataZoneTemp.sharingCutEdges[i])) + bMustPropagate = true; + + dataZoneTemp.sharingCutEdges[i] = TransToEdge[transnum * 8 + flip * 4 + rot][i]; + + if ((pos1 != -1) && (dataZoneTemp.sharingCutEdges[i] != 0)) + pos2 = i; + if ((pos1 == -1) && (dataZoneTemp.sharingCutEdges[i] != 0)) + pos1 = i; + } + // Exchange cutedges != 0 one time /2 to permit all positions + if ((transnum == 1) || (transnum == 4) || (transnum == 7)) + if (zoneBankElement->getName() == zoneBankElementUnder->getName()) + { + bMustPropagate = true; + + dataZoneTemp.sharingCutEdges[pos1] = 3 - dataZoneTemp.sharingCutEdges[pos1]; + dataZoneTemp.sharingCutEdges[pos2] = 3 - dataZoneTemp.sharingCutEdges[pos2]; + } + } + if (dataZoneTemp != dataZoneOriginal) + { + // Add modification landscape + m_zoneBuilder->actionLigoTile(dataZoneTemp, zonePosTemp); + } + updateTrans (x, y, zoneBankElement); + + // If the transition number is not the same propagate the change + if (bMustPropagate) + { + // Propagate where the edge is cut (1/3 or 2/3) and update the transition + if (dataZoneTemp.sharingMatNames[0] != dataZoneTemp.sharingMatNames[2]) + { + if (x > zoneRegion.getMinX ()) + { + // [x-1][y].right = [x][y].left + // _Zones[(x-1-pBZR->getMinX ())+(y-pBZR->getMinY ())*stride].SharingCutEdges[3] = dataZoneTemp.SharingCutEdges[2]; + ZonePosition zonePosTemp2(x - 1, y, m_regionId); + LigoData dataZoneTemp2; + m_zoneBuilder->ligoData(dataZoneTemp2, zonePosTemp2); + if (dataZoneTemp2.sharingCutEdges[3] != dataZoneTemp.sharingCutEdges[2]) + { + dataZoneTemp2.sharingCutEdges[3] = dataZoneTemp.sharingCutEdges[2]; + + // Add modification landscape + m_zoneBuilder->actionLigoTile(dataZoneTemp2, zonePosTemp2); + } + } + updateTrans (x - 1, y); + } + if (dataZoneTemp.sharingMatNames[1] != dataZoneTemp.sharingMatNames[3]) + { + if (x < zoneRegion.getMaxX ()) + { + // [x+1][y].left = [x][y].right + //_Zones[(x+1-pBZR->getMinX ())+(y-pBZR->getMinY ())*stride].SharingCutEdges[2] = dataZoneTemp.SharingCutEdges[3]; + ZonePosition zonePosTemp2(x + 1, y, m_regionId); + LigoData dataZoneTemp2; + m_zoneBuilder->ligoData(dataZoneTemp2, zonePosTemp2); + if (dataZoneTemp2.sharingCutEdges[2] != dataZoneTemp.sharingCutEdges[3]) + { + dataZoneTemp2.sharingCutEdges[2] = dataZoneTemp.sharingCutEdges[3]; + + // Add modification landscape + m_zoneBuilder->actionLigoTile(dataZoneTemp2, zonePosTemp2); + } + } + updateTrans (x + 1, y); + } + if (dataZoneTemp.sharingMatNames[0] != dataZoneTemp.sharingMatNames[1]) + { + if (y > zoneRegion.getMinY ()) + { + // [x][y-1].up = [x][y].down + //_Zones[(x-pBZR->getMinX ())+(y-1-pBZR->getMinY ())*stride].SharingCutEdges[0] = dataZoneTemp.SharingCutEdges[1]; + ZonePosition zonePosTemp2(x, y - 1, m_regionId); + LigoData dataZoneTemp2; + m_zoneBuilder->ligoData(dataZoneTemp2, zonePosTemp2); + if (dataZoneTemp2.sharingCutEdges[0] != dataZoneTemp.sharingCutEdges[1]) + { + dataZoneTemp2.sharingCutEdges[0] = dataZoneTemp.sharingCutEdges[1]; + + // Add modification landscape + m_zoneBuilder->actionLigoTile(dataZoneTemp2, zonePosTemp2); + } + } + updateTrans (x, y - 1); + } + if (dataZoneTemp.sharingMatNames[2] != dataZoneTemp.sharingMatNames[3]) + { + if (y < zoneRegion.getMaxY ()) + { + // [x][y+1].down = [x][y].up + //_Zones[(x-pBZR->getMinX ())+(y+1-pBZR->getMinY ())*stride].SharingCutEdges[1] = dataZoneTemp.SharingCutEdges[0]; + ZonePosition zonePosTemp2(x, y + 1, m_regionId); + LigoData dataZoneTemp2; + m_zoneBuilder->ligoData(dataZoneTemp2, zonePosTemp2); + if (dataZoneTemp2.sharingCutEdges[1] != dataZoneTemp.sharingCutEdges[0]) + { + dataZoneTemp2.sharingCutEdges[1] = dataZoneTemp.sharingCutEdges[0]; + + // Add modification landscape + m_zoneBuilder->actionLigoTile(dataZoneTemp2, zonePosTemp2); + } + } + updateTrans (x, y + 1); + } + } +} + +void BuilderZoneRegion::addToUpdateAndCreate(BuilderZoneRegion* builderZoneRegion, sint32 sharePos, sint32 x, sint32 y, const std::string &newMat, void *pInt1, void *pInt2) +{ + const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion(); + ToUpdate *ptCreate = reinterpret_cast(pInt1); + ToUpdate *ptUpdate = reinterpret_cast(pInt2); + sint32 stride = (1 + zoneRegion.getMaxX() - zoneRegion.getMinX()); + + ZonePosition zonePos; + if (m_zoneBuilder->getZoneAmongRegions(zonePos, builderZoneRegion, x, y)) + { + LigoData data; + m_zoneBuilder->ligoData(data, zonePos); + if (data.sharingMatNames[sharePos] != newMat) + { + data.sharingMatNames[sharePos] = newMat; + + // Add modification landscape + m_zoneBuilder->actionLigoTile(data, zonePos); + } + builderZoneRegion->del(x, y, true, ptUpdate); + ptCreate->add(builderZoneRegion, x, y, newMat); + } +} + +void BuilderZoneRegion::putTransitions (sint32 inX, sint32 inY, const NLLIGO::SPiece &mask, const std::string &matName, + void *pInternal) +{ + const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion(); + ToUpdate tCreate; // Transition to create + ToUpdate *ptUpdate = reinterpret_cast(pInternal); // Transition to update + + sint32 i, j, k, l, m; + sint32 x = inX, y = inY; + for (j = 0; j < mask.h; ++j) + for (i = 0; i < mask.w; ++i) + if (mask.Tab[i + j * mask.w]) + { + for (k = -1; k <= 1; ++k) + for (l = -1; l <= 1; ++l) + { + BuilderZoneRegion *builderZoneRegion2 = this; + ZonePosition zonePos; + if (m_zoneBuilder->getZoneAmongRegions(zonePos, builderZoneRegion2, inX + i + l, inY + j + k)) + tCreate.add(builderZoneRegion2, inX + i + l, inY + j + k, matName); + } + } + + // Check coherency of the transition to update + for (m = 0; m < (sint32)tCreate.size(); ++m) + { + BuilderZoneRegion *builderZoneRegion2 = tCreate.getBuilderZoneRegion(m); + x = tCreate.getX(m); + y = tCreate.getY(m); + std::string putMat = tCreate.getMat(m); + + //if ((x < pBZR->getMinX ())||(x > pBZR->getMaxX ())||(y < pBZR->getMinY ())||(y > pBZR->getMaxY ())) + // continue; + + ZonePosition zoneTemp(x, y, builderZoneRegion2->getRegionId()); + LigoData dataZoneTemp; + m_zoneBuilder->ligoData(dataZoneTemp, zoneTemp); + + if (!((dataZoneTemp.sharingMatNames[0] == dataZoneTemp.sharingMatNames[1])&& + (dataZoneTemp.sharingMatNames[1] == dataZoneTemp.sharingMatNames[2])&& + (dataZoneTemp.sharingMatNames[2] == dataZoneTemp.sharingMatNames[3]))) + builderZoneRegion2->del(x, y, true, ptUpdate); + + // Check to see material can be posed + uint corner; + for (corner = 0; corner < 4; corner++) + { + std::string newMat = getNextMatInTree (putMat, dataZoneTemp.sharingMatNames[corner]); + + // Can't be posed ? + if (newMat == STRING_UNUSED) + break; + } + if ( (corner < 4) && (m != 0) ) + { + // The material can't be paused + dataZoneTemp.sharingMatNames[0] = STRING_UNUSED; + dataZoneTemp.sharingMatNames[1] = STRING_UNUSED; + dataZoneTemp.sharingMatNames[2] = STRING_UNUSED; + dataZoneTemp.sharingMatNames[3] = STRING_UNUSED; + + // Don't propagate any more + } + else + { + // Expand material for the 1st quarter + std::string newMat = getNextMatInTree(putMat, dataZoneTemp.sharingMatNames[0]); + if (newMat != dataZoneTemp.sharingMatNames[0]) + { + // Update the quarter + if (dataZoneTemp.sharingMatNames[0] != newMat) + { + dataZoneTemp.sharingMatNames[0] = newMat; + + // Add modification landscape + m_zoneBuilder->actionLigoTile(dataZoneTemp, zoneTemp); + } + + addToUpdateAndCreate(builderZoneRegion2, 1, x - 1, y, newMat, &tCreate, ptUpdate); + addToUpdateAndCreate(builderZoneRegion2, 3, x - 1, y - 1, newMat, &tCreate, ptUpdate); + addToUpdateAndCreate(builderZoneRegion2, 2, x, y - 1, newMat, &tCreate, ptUpdate); + } + + // Expand material for the 2nd quarter + newMat = getNextMatInTree(putMat, dataZoneTemp.sharingMatNames[1]); + if (newMat != dataZoneTemp.sharingMatNames[1]) + { + // Update the quarter + //if (_Builder->getZoneMask(x,y)) + if (dataZoneTemp.sharingMatNames[1] != newMat) + { + dataZoneTemp.sharingMatNames[1] = newMat; + + // Add modification landscape + m_zoneBuilder->actionLigoTile(dataZoneTemp, zoneTemp); + } + + addToUpdateAndCreate(builderZoneRegion2, 0, x + 1, y, newMat, &tCreate, ptUpdate); + addToUpdateAndCreate(builderZoneRegion2, 2, x + 1, y - 1, newMat, &tCreate, ptUpdate); + addToUpdateAndCreate(builderZoneRegion2, 3, x, y - 1, newMat, &tCreate, ptUpdate); + } + + // Expand material for the 3rd quarter + newMat = getNextMatInTree(putMat, dataZoneTemp.sharingMatNames[2]); + if (newMat != dataZoneTemp.sharingMatNames[2]) + { + // Update the quarter + //if (_Builder->getZoneMask(x,y)) + if (dataZoneTemp.sharingMatNames[2] != newMat) + { + dataZoneTemp.sharingMatNames[2] = newMat; + + // Add modification landscape + m_zoneBuilder->actionLigoTile(dataZoneTemp, zoneTemp); + } + + addToUpdateAndCreate(builderZoneRegion2, 3, x - 1, y, newMat, &tCreate, ptUpdate); + addToUpdateAndCreate(builderZoneRegion2, 1, x - 1, y + 1, newMat, &tCreate, ptUpdate); + addToUpdateAndCreate(builderZoneRegion2, 0, x, y + 1, newMat, &tCreate, ptUpdate); + } + + // Expand material for the 4th quarter + newMat = getNextMatInTree(putMat, dataZoneTemp.sharingMatNames[3]); + if (newMat != dataZoneTemp.sharingMatNames[3]) + { + // Update the quarter + //if (_Builder->getZoneMask(x,y)) + if (dataZoneTemp.sharingMatNames[3] != newMat) + { + dataZoneTemp.sharingMatNames[3] = newMat; + + // Add modification landscape + m_zoneBuilder->actionLigoTile(dataZoneTemp, zoneTemp); + } + + addToUpdateAndCreate(builderZoneRegion2, 2, x + 1, y, newMat, &tCreate, ptUpdate); + addToUpdateAndCreate(builderZoneRegion2, 0, x + 1, y + 1, newMat, &tCreate, ptUpdate); + addToUpdateAndCreate(builderZoneRegion2, 1, x, y + 1, newMat, &tCreate, ptUpdate); + } + } + + // Add modification landscape + m_zoneBuilder->actionLigoTile(dataZoneTemp, zoneTemp); + } + + // Delete transitions that are inside the mask + for (j = 0; j < mask.h; ++j) + for (i = 0; i < mask.w; ++i) + if (mask.Tab[i + j * mask.w]) + { + tCreate.del(inX + i, inY + j); + } + + // For all transition to update choose the cut edge + for (m = 0; m < (sint32)tCreate.size(); ++m) + { + const NLLIGO::CZoneRegion &zoneRegion2 = m_zoneBuilder->zoneRegion(tCreate.getBuilderZoneRegion(m)->getRegionId())->zoneRegion(); + x = tCreate.getX(m); + y = tCreate.getY(m); + + if ((x < zoneRegion.getMinX()) || (x > zoneRegion.getMaxX()) || + (y < zoneRegion.getMinY()) || (y > zoneRegion.getMaxY())) + continue; + + ZonePosition zoneTemp(x, y, tCreate.getBuilderZoneRegion(m)->getRegionId()); + LigoData dataZoneTemp; + m_zoneBuilder->ligoData(dataZoneTemp, zoneTemp); + LigoData dataZoneTempOriginal = dataZoneTemp; + + for (i = 0; i < 4; ++i) + { + uint8 nCut = (uint8)(1.0f + NLMISC::frand(2.0f)); + NLMISC::clamp(nCut, (uint8)1, (uint8)2); + dataZoneTemp.sharingCutEdges[i] = nCut; + } + + // Add modification landscape + if (dataZoneTempOriginal != dataZoneTemp) + m_zoneBuilder->actionLigoTile(dataZoneTemp, zoneTemp); + + // Propagate + if (dataZoneTemp.sharingMatNames[0] != dataZoneTemp.sharingMatNames[2]) + { + // [x-1][y].right = [x][y].left + BuilderZoneRegion *builderZoneRegion3 = tCreate.getBuilderZoneRegion(m); + ZonePosition zonePosU; + if (m_zoneBuilder->getZoneAmongRegions(zonePosU, builderZoneRegion3, x - 1, y)) + { + LigoData data; + m_zoneBuilder->ligoData(data, zonePosU); + if (data.sharingCutEdges[3] != dataZoneTemp.sharingCutEdges[2]) + { + data.sharingCutEdges[3] = dataZoneTemp.sharingCutEdges[2]; + + // Add modification landscape + m_zoneBuilder->actionLigoTile(data, zonePosU); + } + ptUpdate->add(builderZoneRegion3, x - 1, y, ""); + } + } + else + { + m_zoneBuilder->ligoData(dataZoneTemp, zoneTemp); + if (dataZoneTemp.sharingCutEdges[2] != 0) + { + dataZoneTemp.sharingCutEdges[2] = 0; + + // Add modification landscape + m_zoneBuilder->actionLigoTile(dataZoneTemp, zoneTemp); + } + } + + if (dataZoneTemp.sharingMatNames[0] != dataZoneTemp.sharingMatNames[1]) + { + // [x][y-1].up = [x][y].down + BuilderZoneRegion *builderZoneRegion3 = tCreate.getBuilderZoneRegion(m); + ZonePosition zonePosU; + if (m_zoneBuilder->getZoneAmongRegions (zonePosU, builderZoneRegion3, x, y - 1)) + { + LigoData data; + m_zoneBuilder->ligoData(data, zonePosU); + if (data.sharingCutEdges[0] != dataZoneTemp.sharingCutEdges[1]) + { + data.sharingCutEdges[0] = dataZoneTemp.sharingCutEdges[1]; + + // Add modification landscape + m_zoneBuilder->actionLigoTile(data, zonePosU); + } + ptUpdate->add (builderZoneRegion3, x, y - 1, ""); + } + } + else + { + m_zoneBuilder->ligoData(dataZoneTemp, zoneTemp); + if (dataZoneTemp.sharingCutEdges[1] != 0) + { + dataZoneTemp.sharingCutEdges[1] = 0; + + // Add modification landscape + m_zoneBuilder->actionLigoTile(dataZoneTemp, zoneTemp); + } + } + + if (dataZoneTemp.sharingMatNames[3] != dataZoneTemp.sharingMatNames[1]) + { + // [x+1][y].left = [x][y].right + BuilderZoneRegion *builderZoneRegion3 = tCreate.getBuilderZoneRegion(m); + ZonePosition zonePosU; + if (m_zoneBuilder->getZoneAmongRegions(zonePosU, builderZoneRegion3, x + 1, y)) + { + LigoData data; + m_zoneBuilder->ligoData(data, zonePosU); + if (data.sharingCutEdges[2] != dataZoneTemp.sharingCutEdges[3]) + { + data.sharingCutEdges[2] = dataZoneTemp.sharingCutEdges[3]; + + // Add modification landscape + m_zoneBuilder->actionLigoTile(data, zonePosU); + } + ptUpdate->add(builderZoneRegion3, x + 1, y, ""); + } + } + else + { + m_zoneBuilder->ligoData(dataZoneTemp, zoneTemp); + if (dataZoneTemp.sharingCutEdges[3] != 0) + { + dataZoneTemp.sharingCutEdges[3] = 0; + + // Add modification landscape + m_zoneBuilder->actionLigoTile(dataZoneTemp, zoneTemp); + } + } + + if (dataZoneTemp.sharingMatNames[2] != dataZoneTemp.sharingMatNames[3]) + { + // [x][y+1].down = [x][y].up + BuilderZoneRegion *builderZoneRegion3 = tCreate.getBuilderZoneRegion(m); + ZonePosition zonePosU; + if (m_zoneBuilder->getZoneAmongRegions (zonePosU, builderZoneRegion3, x, y+1)) + { + LigoData data; + m_zoneBuilder->ligoData(data, zonePosU); + if (data.sharingCutEdges[1] = dataZoneTemp.sharingCutEdges[0]) + { + data.sharingCutEdges[1] = dataZoneTemp.sharingCutEdges[0]; + + // Add modification landscape + m_zoneBuilder->actionLigoTile(data, zonePosU); + } + ptUpdate->add (builderZoneRegion3, x, y + 1, ""); + } + } + else + { + m_zoneBuilder->ligoData(dataZoneTemp, zoneTemp); + if (dataZoneTemp.sharingCutEdges[0] = 0) + { + dataZoneTemp.sharingCutEdges[0] = 0; + + // Add modification landscape + m_zoneBuilder->actionLigoTile(dataZoneTemp, zoneTemp); + } + } + } + + // Delete in tUpdate each element in common with tCreate + for (m = 0; m < (sint32)tCreate.size(); ++m) + { + x = tCreate.getX(m); + y = tCreate.getY(m); + ptUpdate->del (x,y); + } + + // Finally update all transition + for (m = 0; m < (sint32)tCreate.size(); ++m) + { + const NLLIGO::CZoneRegion &zoneRegion2 = m_zoneBuilder->zoneRegion(tCreate.getBuilderZoneRegion(m)->getRegionId())->zoneRegion(); + x = tCreate.getX(m); + y = tCreate.getY(m); + + if ((x >= zoneRegion2.getMinX()) && (x <= zoneRegion2.getMaxX()) && + (y >= zoneRegion2.getMinY()) && (y <= zoneRegion2.getMaxY())) + tCreate.getBuilderZoneRegion(m)->updateTrans(x, y); + } + for (m = 0; m < (sint32)ptUpdate->size(); ++m) + { + const NLLIGO::CZoneRegion &zoneRegion2 = m_zoneBuilder->zoneRegion(tCreate.getBuilderZoneRegion(m)->getRegionId())->zoneRegion(); + x = ptUpdate->getX(m); + y = ptUpdate->getY(m); + if ((x >= zoneRegion2.getMinX()) && (x <= zoneRegion2.getMaxX()) && + (y >= zoneRegion2.getMinY()) && (y <= zoneRegion2.getMaxY())) + tCreate.getBuilderZoneRegion(m)->updateTrans(x, y); + } + + // Cross material + for (m = 0; m < (sint32)tCreate.size(); ++m) + { + const NLLIGO::CZoneRegion &zoneRegion2 = m_zoneBuilder->zoneRegion(tCreate.getBuilderZoneRegion(m)->getRegionId())->zoneRegion(); + x = tCreate.getX(m); + y = tCreate.getY(m); + + + ZonePosition zoneTemp(x, y, m_regionId); + LigoData dataZoneTemp; + m_zoneBuilder->ligoData(dataZoneTemp, zoneTemp); + + std::set matNameSet; + for (i = 0; i < 4; ++i) + matNameSet.insert(dataZoneTemp.sharingMatNames[i]); + + if (((dataZoneTemp.sharingMatNames[0] == dataZoneTemp.sharingMatNames[3]) && + (dataZoneTemp.sharingMatNames[1] == dataZoneTemp.sharingMatNames[2]) && + (dataZoneTemp.sharingMatNames[0] != dataZoneTemp.sharingMatNames[1])) + || (matNameSet.size()>2)) + { + NLLIGO::CZoneBank &zoneBank = m_zoneBuilder->getZoneBank(); + zoneBank.resetSelection(); + zoneBank.addOrSwitch("material", tCreate.getMat(m)); + zoneBank.addAndSwitch("size", "1x1"); + std::vector vElts; + zoneBank.getSelection(vElts); + if (vElts.size() == 0) + return; + sint32 nRan = (sint32)(NLMISC::frand((float)vElts.size())); + NLMISC::clamp(nRan, (sint32)0, (sint32)(vElts.size() - 1)); + NLLIGO::CZoneBankElement *zoneBankElement = vElts[nRan]; + nRan = (uint32)(NLMISC::frand (1.0) * 4); + NLMISC::clamp(nRan, (sint32)0, (sint32)3); + uint8 rot = (uint8)nRan; + nRan = (uint32)(NLMISC::frand (1.0) * 2); + NLMISC::clamp (nRan, (sint32)0, (sint32)1); + uint8 flip = (uint8)nRan; + + tCreate.getBuilderZoneRegion(m)->add(x, y, rot, flip, zoneBankElement); + } + } +} + +struct STrans +{ + uint8 Num; + uint8 Rot; + uint8 Flip; +}; + +STrans TranConvTable[128] = +{ + { 0,0,0 }, // Quart = 0, CutEdge = 0, Np = 0 UNUSED + { 0,0,0 }, // Quart = 0, CutEdge = 0, Np = 1 UNUSED + { 0,0,0 }, // Quart = 0, CutEdge = 1, Np = 0 UNUSED + { 0,0,0 }, // Quart = 0, CutEdge = 1, Np = 1 UNUSED + { 0,0,0 }, // Quart = 0, CutEdge = 2, Np = 0 UNUSED + { 0,0,0 }, // Quart = 0, CutEdge = 2, Np = 1 UNUSED + { 0,0,0 }, // Quart = 0, CutEdge = 3, Np = 0 UNUSED + { 0,0,0 }, // Quart = 0, CutEdge = 3, Np = 1 UNUSED + + { 6,0,0 }, // Quart = 1, CutEdge = 0, Np = 0 + { 6,3,1 }, // Quart = 1, CutEdge = 0, Np = 1 + { 7,0,0 }, // Quart = 1, CutEdge = 1, Np = 0 + { 7,0,0 }, // Quart = 1, CutEdge = 1, Np = 1 + { 7,3,1 }, // Quart = 1, CutEdge = 2, Np = 0 + { 7,3,1 }, // Quart = 1, CutEdge = 2, Np = 1 + { 8,0,0 }, // Quart = 1, CutEdge = 3, Np = 0 + { 8,3,1 }, // Quart = 1, CutEdge = 3, Np = 1 + + { 7,0,1 }, // Quart = 2, CutEdge = 0, Np = 0 + { 7,0,1 }, // Quart = 2, CutEdge = 0, Np = 1 + { 6,0,1 }, // Quart = 2, CutEdge = 1, Np = 0 + { 6,1,0 }, // Quart = 2, CutEdge = 1, Np = 1 + { 8,1,0 }, // Quart = 2, CutEdge = 2, Np = 0 + { 8,0,1 }, // Quart = 2, CutEdge = 2, Np = 1 + { 7,1,0 }, // Quart = 2, CutEdge = 3, Np = 0 + { 7,1,0 }, // Quart = 2, CutEdge = 3, Np = 1 + + { 0,0,0 }, // Quart = 3, CutEdge = 0, Np = 0 + { 0,0,1 }, // Quart = 3, CutEdge = 0, Np = 1 + { 1,0,1 }, // Quart = 3, CutEdge = 1, Np = 0 + { 1,0,1 }, // Quart = 3, CutEdge = 1, Np = 1 + { 1,0,0 }, // Quart = 3, CutEdge = 2, Np = 0 + { 1,0,0 }, // Quart = 3, CutEdge = 2, Np = 1 + { 2,0,0 }, // Quart = 3, CutEdge = 3, Np = 0 + { 2,0,1 }, // Quart = 3, CutEdge = 3, Np = 1 + + { 7,3,0 }, // Quart = 4, CutEdge = 0, Np = 0 + { 7,3,0 }, // Quart = 4, CutEdge = 0, Np = 1 + { 8,3,0 }, // Quart = 4, CutEdge = 1, Np = 0 + { 8,2,1 }, // Quart = 4, CutEdge = 1, Np = 1 + { 6,3,0 }, // Quart = 4, CutEdge = 2, Np = 0 + { 6,2,1 }, // Quart = 4, CutEdge = 2, Np = 1 + { 7,2,1 }, // Quart = 4, CutEdge = 3, Np = 0 + { 7,2,1 }, // Quart = 4, CutEdge = 3, Np = 1 + + { 0,3,0 }, // Quart = 5, CutEdge = 0, Np = 0 + { 0,3,1 }, // Quart = 5, CutEdge = 0, Np = 1 + { 1,3,1 }, // Quart = 5, CutEdge = 1, Np = 0 + { 1,3,1 }, // Quart = 5, CutEdge = 1, Np = 1 + { 1,3,0 }, // Quart = 5, CutEdge = 2, Np = 0 + { 1,3,0 }, // Quart = 5, CutEdge = 2, Np = 1 + { 2,3,0 }, // Quart = 5, CutEdge = 3, Np = 0 + { 2,3,1 }, // Quart = 5, CutEdge = 3, Np = 1 + + { 0,0,0 }, // Quart = 6, CutEdge = 0, Np = 0 UNUSED + { 0,0,0 }, // Quart = 6, CutEdge = 0, Np = 1 UNUSED + { 0,0,0 }, // Quart = 6, CutEdge = 1, Np = 0 UNUSED + { 0,0,0 }, // Quart = 6, CutEdge = 1, Np = 1 UNUSED + { 0,0,0 }, // Quart = 6, CutEdge = 2, Np = 0 UNUSED + { 0,0,0 }, // Quart = 6, CutEdge = 2, Np = 1 UNUSED + { 0,0,0 }, // Quart = 6, CutEdge = 3, Np = 0 UNUSED + { 0,0,0 }, // Quart = 6, CutEdge = 3, Np = 1 UNUSED + + { 5,2,0 }, // Quart = 7, CutEdge = 0, Np = 0 + { 5,1,1 }, // Quart = 7, CutEdge = 0, Np = 1 + { 4,1,1 }, // Quart = 7, CutEdge = 1, Np = 0 + { 4,1,1 }, // Quart = 7, CutEdge = 1, Np = 1 + { 4,2,0 }, // Quart = 7, CutEdge = 2, Np = 0 + { 4,2,0 }, // Quart = 7, CutEdge = 2, Np = 1 + { 3,2,0 }, // Quart = 7, CutEdge = 3, Np = 0 + { 3,1,1 }, // Quart = 7, CutEdge = 3, Np = 1 + + { 8,2,0 }, // Quart = 8, CutEdge = 0, Np = 0 + { 8,1,1 }, // Quart = 8, CutEdge = 0, Np = 1 + { 7,1,1 }, // Quart = 8, CutEdge = 1, Np = 0 + { 7,1,1 }, // Quart = 8, CutEdge = 1, Np = 1 + { 7,2,0 }, // Quart = 8, CutEdge = 2, Np = 0 + { 7,2,0 }, // Quart = 8, CutEdge = 2, Np = 1 + { 6,2,0 }, // Quart = 8, CutEdge = 3, Np = 0 + { 6,1,1 }, // Quart = 8, CutEdge = 3, Np = 1 + + { 0,0,0 }, // Quart = 9, CutEdge = 0, Np = 0 UNUSED + { 0,0,0 }, // Quart = 9, CutEdge = 0, Np = 1 UNUSED + { 0,0,0 }, // Quart = 9, CutEdge = 1, Np = 0 UNUSED + { 0,0,0 }, // Quart = 9, CutEdge = 1, Np = 1 UNUSED + { 0,0,0 }, // Quart = 9, CutEdge = 2, Np = 0 UNUSED + { 0,0,0 }, // Quart = 9, CutEdge = 2, Np = 1 UNUSED + { 0,0,0 }, // Quart = 9, CutEdge = 3, Np = 0 UNUSED + { 0,0,0 }, // Quart = 9, CutEdge = 3, Np = 1 UNUSED + + { 2,1,0 }, // Quart = 10, CutEdge = 0, Np = 0 + { 2,1,1 }, // Quart = 10, CutEdge = 0, Np = 1 + { 1,1,1 }, // Quart = 10, CutEdge = 1, Np = 0 + { 1,1,1 }, // Quart = 10, CutEdge = 1, Np = 1 + { 1,1,0 }, // Quart = 10, CutEdge = 2, Np = 0 + { 1,1,0 }, // Quart = 10, CutEdge = 2, Np = 1 + { 0,1,0 }, // Quart = 10, CutEdge = 3, Np = 0 + { 0,1,1 }, // Quart = 10, CutEdge = 3, Np = 1 + + { 4,3,0 }, // Quart = 11, CutEdge = 0, Np = 0 + { 4,3,0 }, // Quart = 11, CutEdge = 0, Np = 1 + { 5,3,0 }, // Quart = 11, CutEdge = 1, Np = 0 + { 5,2,1 }, // Quart = 11, CutEdge = 1, Np = 1 + { 3,3,0 }, // Quart = 11, CutEdge = 2, Np = 0 + { 3,2,1 }, // Quart = 11, CutEdge = 2, Np = 1 + { 4,2,1 }, // Quart = 11, CutEdge = 3, Np = 0 + { 4,2,1 }, // Quart = 11, CutEdge = 3, Np = 1 + + { 2,2,0 }, // Quart = 12, CutEdge = 0, Np = 0 + { 2,2,1 }, // Quart = 12, CutEdge = 0, Np = 1 + { 1,2,1 }, // Quart = 12, CutEdge = 1, Np = 0 + { 1,2,1 }, // Quart = 12, CutEdge = 1, Np = 1 + { 1,2,0 }, // Quart = 12, CutEdge = 2, Np = 0 + { 1,2,0 }, // Quart = 12, CutEdge = 2, Np = 1 + { 0,2,0 }, // Quart = 12, CutEdge = 3, Np = 0 + { 0,2,1 }, // Quart = 12, CutEdge = 3, Np = 1 + + { 4,0,1 }, // Quart = 13, CutEdge = 0, Np = 0 + { 4,0,1 }, // Quart = 13, CutEdge = 0, Np = 1 + { 3,1,0 }, // Quart = 13, CutEdge = 1, Np = 0 + { 3,0,1 }, // Quart = 13, CutEdge = 1, Np = 1 + { 5,1,0 }, // Quart = 13, CutEdge = 2, Np = 0 + { 5,0,1 }, // Quart = 13, CutEdge = 2, Np = 1 + { 4,1,0 }, // Quart = 13, CutEdge = 3, Np = 0 + { 4,1,0 }, // Quart = 13, CutEdge = 3, Np = 1 + + { 3,0,0 }, // Quart = 14, CutEdge = 0, Np = 0 + { 3,3,1 }, // Quart = 14, CutEdge = 0, Np = 1 + { 4,0,0 }, // Quart = 14, CutEdge = 1, Np = 0 + { 4,0,0 }, // Quart = 14, CutEdge = 1, Np = 1 + { 4,3,1 }, // Quart = 14, CutEdge = 2, Np = 0 + { 4,3,1 }, // Quart = 14, CutEdge = 2, Np = 1 + { 5,0,0 }, // Quart = 14, CutEdge = 3, Np = 0 + { 5,3,1 }, // Quart = 14, CutEdge = 3, Np = 1 + + { 0,0,0 }, // Quart = 15, CutEdge = 0, Np = 0 UNUSED + { 0,0,0 }, // Quart = 15, CutEdge = 0, Np = 1 UNUSED + { 0,0,0 }, // Quart = 15, CutEdge = 1, Np = 0 UNUSED + { 0,0,0 }, // Quart = 15, CutEdge = 1, Np = 1 UNUSED + { 0,0,0 }, // Quart = 15, CutEdge = 2, Np = 0 UNUSED + { 0,0,0 }, // Quart = 15, CutEdge = 2, Np = 1 UNUSED + { 0,0,0 }, // Quart = 15, CutEdge = 3, Np = 0 UNUSED + { 0,0,0 } // Quart = 15, CutEdge = 3, Np = 1 UNUSED +}; + +void BuilderZoneRegion::updateTrans (sint32 x, sint32 y, NLLIGO::CZoneBankElement *zoneBankElement) +{ + const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion(); + if ((x < zoneRegion.getMinX()) || (x > zoneRegion.getMaxX()) || + (y < zoneRegion.getMinY()) || (y > zoneRegion.getMaxY())) + return; + + //if (!_Builder->getZoneMask(x,y)) + // return; + + // Interpret the transition info + x -= zoneRegion.getMinX (); + y -= zoneRegion.getMinY (); + sint32 m; + + // Calculate the number of material around with transition info + std::set matNameSet; + + ZonePosition zonePosTemp(x + zoneRegion.getMinX(), y + zoneRegion.getMinY(), m_regionId); + LigoData dataZoneTemp; + m_zoneBuilder->ligoData(dataZoneTemp, zonePosTemp); + LigoData dataZoneTempOriginal = dataZoneTemp; + + for (m = 0; m < 4; ++m) + matNameSet.insert(dataZoneTemp.sharingMatNames[m]); + + if (matNameSet.size() == 1) + { + if (dataZoneTemp.sharingMatNames[0] == STRING_UNUSED) + { + del(x + zoneRegion.getMinX (), y + zoneRegion.getMinY ()); + // set (x+pBZR->getMinX (), y+pBZR->getMinY (), 0, 0, STRING_UNUSED, false); + return; + } + else + { + NLLIGO::CZoneBankElement *zoneBankElement2 = m_zoneBuilder->getZoneBank().getElementByZoneName(dataZoneTemp.zoneName); + if ((zoneBankElement != NULL) && (zoneBankElement2->getCategory("material") == dataZoneTemp.sharingMatNames[0])) + return; + + NLLIGO::CZoneBank &zoneBank = m_zoneBuilder->getZoneBank(); + zoneBank.resetSelection (); + zoneBank.addOrSwitch ("material", dataZoneTemp.sharingMatNames[0]); + zoneBank.addAndSwitch ("size", "1x1"); + std::vector vElts; + zoneBank.getSelection (vElts); + if (vElts.size() == 0) + return; + sint32 nRan = (sint32)(NLMISC::frand((float)vElts.size())); + NLMISC::clamp (nRan, (sint32)0, (sint32)(vElts.size()-1)); + zoneBankElement = vElts[nRan]; + nRan = (uint32)(NLMISC::frand(1.0) * 4); + NLMISC::clamp (nRan, (sint32)0, (sint32)3); + uint8 rot = (uint8)nRan; + nRan = (uint32)(NLMISC::frand(1.0) * 2); + NLMISC::clamp (nRan, (sint32)0, (sint32)1); + uint8 flip = (uint8)nRan; + + set(x + zoneRegion.getMinX(), y + zoneRegion.getMinY(), 0, 0, zoneBankElement->getName(), false); + setRot(x + zoneRegion.getMinX(), y + zoneRegion.getMinY(), rot); + setFlip(x + zoneRegion.getMinX(), y + zoneRegion.getMinY(), flip); + return; + } + } + + // No 2 materials so the transition system dont work + if (matNameSet.size() != 2) + return; + + std::set::iterator it = matNameSet.begin(); + std::string matA = *it; + ++it; + std::string matB = *it; + + NLLIGO::CZoneBank &zoneBank = m_zoneBuilder->getZoneBank(); + zoneBank.resetSelection (); + zoneBank.addOrSwitch("transname", matA + "-" + matB); + std::vector selection; + zoneBank.getSelection(selection); + if (selection.size() == 0) + { + std::string matTmp = matA; + matA = matB; + matB = matTmp; + zoneBank.resetSelection (); + zoneBank.addOrSwitch ("transname", matA + "-" + matB); + zoneBank.getSelection (selection); + } + + if (selection.size() == 0) + return; + + // Convert the sharingCutEdges and SharingNames to the num and type of transition + uint8 nQuart = 0; // 0-MatA 1-MatB + for (m = 0; m < 4; ++m) + if (dataZoneTemp.sharingMatNames[m] == matB) + nQuart |= (1 << m); + + if ((nQuart == 0) || (nQuart == 6) || + (nQuart == 9) || (nQuart == 15)) + return; // No transition for those types + + uint8 nCutEdge = 0; + uint8 nPosCorner = 0; + + // If up edge is cut write the cut position in nCutEdge bitfield (1->0, 2->1) + if ((nQuart == 4) || (nQuart == 5) || + (nQuart == 7) || (nQuart == 8) || + (nQuart == 10) || (nQuart == 11)) + { + if (dataZoneTemp.sharingCutEdges[0] == 2) + nCutEdge |= 1 << nPosCorner; + ++nPosCorner; + } + else + { + dataZoneTemp.sharingCutEdges[0] = 0; + } + + // Same for down edge + if ((nQuart == 1) || (nQuart == 2) || + (nQuart == 5) || (nQuart == 10) || + (nQuart == 13) || (nQuart == 14)) + { + if (dataZoneTemp.sharingCutEdges[1] == 2) + nCutEdge |= 1 << nPosCorner; + ++nPosCorner; + } + else + { + dataZoneTemp.sharingCutEdges[1] = 0; + } + + // Same for left edge + if ((nQuart == 1) || (nQuart == 3) || + (nQuart == 4) ||(nQuart == 11) || + (nQuart == 12) || (nQuart == 14)) + { + if (dataZoneTemp.sharingCutEdges[2] == 2) + nCutEdge |= 1 << nPosCorner; + ++nPosCorner; + } + else + { + dataZoneTemp.sharingCutEdges[2] = 0; + } + + // Same for right edge + if ((nQuart == 2) || (nQuart == 3) || + (nQuart == 7) || (nQuart == 8) || + (nQuart == 12) || (nQuart == 13)) + { + if (dataZoneTemp.sharingCutEdges[3] == 2) + nCutEdge |= 1 << nPosCorner; + ++nPosCorner; + } + else + { + dataZoneTemp.sharingCutEdges[3] = 0; + } + + nlassert (nPosCorner == 2); // If not this means that more than 2 edges are cut which is not possible + + STrans Trans, TransTmp1, TransTmp2; + + TransTmp1 = TranConvTable[nQuart * 8 + 2 * nCutEdge + 0]; + TransTmp2 = TranConvTable[nQuart * 8 + 2 * nCutEdge + 1]; + + // Choose one or the two + sint32 nTrans = (sint32)(NLMISC::frand(2.0f)); + NLMISC::clamp(nTrans, (sint32)0, (sint32)1); + if (nTrans == 0) + Trans = TransTmp1; + else + Trans = TransTmp2; + + zoneBank.addAndSwitch ("transnum", NLMISC::toString(Trans.Num)); + zoneBank.getSelection (selection); + + if (selection.size() > 0) + { + if (zoneBankElement != NULL) + { + dataZoneTemp.zoneName = zoneBankElement->getName(); + } + else + { + nTrans = (uint32)(NLMISC::frand (1.0) * selection.size()); + NLMISC::clamp(nTrans, (sint32)0, (sint32)(selection.size() - 1)); + dataZoneTemp.zoneName = selection[nTrans]->getName(); + } + dataZoneTemp.posX = dataZoneTemp.posY = 0; + dataZoneTemp.rot = Trans.Rot; + dataZoneTemp.flip = Trans.Flip; + } + + // Add modification landscape + if (dataZoneTempOriginal != dataZoneTemp) + m_zoneBuilder->actionLigoTile(dataZoneTemp, zonePosTemp); +} + +std::string BuilderZoneRegion::getNextMatInTree (const std::string &matA, const std::string &matB) +{ + const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion(); + uint32 i, posA = 10000, posB = 10000; + + if (matA == matB) + return matA; + + for (i = 0; i < m_matTree.size(); ++i) + { + if (m_matTree[i].Name == matA) + posA = i; + if (m_matTree[i].Name == matB) + posB = i; + } + if ((posA == 10000) || (posB == 10000)) + return STRING_UNUSED; + + std::vector vTemp; + tryPath (posA, posB, vTemp); + if (vTemp.size() <= 1) + return STRING_UNUSED; + else + return m_matTree[vTemp[1]].Name; +} + +struct SNode +{ + sint32 NodePos, Dist, PrevNodePos; + + SNode() + { + NodePos = Dist = PrevNodePos = -1; + } +}; + +void BuilderZoneRegion::tryPath(uint32 posA, uint32 posB, std::vector &path) +{ + const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion(); + + // Build the adjascence matrix + std::vector matAdj; + sint32 numNodes = m_matTree.size(); + sint32 i, j, cost; + matAdj.resize(numNodes * numNodes, -1); + for (i = 0; i < numNodes; ++i) + for (j = 0; j < (sint32)m_matTree[i].Arcs.size(); ++j) + matAdj[i + m_matTree[i].Arcs[j] * numNodes] = 1; + + std::vector vNodes; // NodesPos == index + vNodes.resize (numNodes); + for (i = 0; i < numNodes; ++i) + vNodes[i].NodePos = i; + vNodes[posA].Dist = 0; + + std::queue qNodes; + qNodes.push (vNodes[posA]); + + while (qNodes.size() > 0) + { + SNode node = qNodes.front(); + qNodes.pop (); + + for (i = 0; i < numNodes; ++i) + { + cost = matAdj[node.NodePos + i * numNodes]; + if (cost != -1) + { + if ((vNodes[i].Dist == -1) || (vNodes[i].Dist > (cost + node.Dist))) + { + vNodes[i].Dist = cost + node.Dist; + vNodes[i].PrevNodePos = node.NodePos; + qNodes.push(vNodes[i]); + } + } + } + } + + // Get path length + i = posB; + j = 0; + while (i != -1) + { + ++j; + i = vNodes[i].PrevNodePos; + } + + // Write the path in the good order (from posA to posB) + path.resize(j); + i = posB; + while (i != -1) + { + --j; + path[j] = i; + i = vNodes[i].PrevNodePos; + } +} + +void BuilderZoneRegion::del(sint32 x, sint32 y, bool transition, void *pInternal) +{ + const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion(); + if (!m_zoneBuilder->getZoneMask(x, y)) + return; + + const std::string &nameZone = zoneRegion.getName(x, y); + + ToUpdate *pUpdate = reinterpret_cast(pInternal); + + NLLIGO::CZoneBankElement *zoneBankElement = m_zoneBuilder->getZoneBank().getElementByZoneName(nameZone); + if (zoneBankElement != NULL) + { + sint32 sizeX = zoneBankElement->getSizeX(), sizeY = zoneBankElement->getSizeY(); + sint32 posX = zoneRegion.getPosX (x, y), posY = zoneRegion.getPosY (x, y); + uint8 rot = zoneRegion.getRot (x, y); + uint8 flip = zoneRegion.getFlip (x, y); + sint32 i, j; + sint32 deltaX, deltaY; + + if (flip == 0) + { + switch (rot) + { + case 0: + deltaX = -posX; + deltaY = -posY; + break; + case 1: + deltaX = -(sizeY - 1 - posY); + deltaY = -posX; + break; + case 2: + deltaX = -(sizeX - 1 - posX); + deltaY = -(sizeY - 1 - posY); + break; + case 3: + deltaX = -posY; + deltaY = -(sizeX - 1 - posX); + break; + } + } + else + { + switch (rot) + { + case 0: + deltaX = -(sizeX - 1 - posX); + deltaY = -posY; + break; + case 1: + deltaX = -(sizeY - 1 - posY); + deltaY = -(sizeX - 1 - posX); + break; + case 2: + deltaX = -posX; + deltaY = -(sizeY - 1 - posY); + break; + case 3: + deltaX = -posY; + deltaY = -posX; + break; + } + } + + NLLIGO::SPiece mask; + mask.Tab.resize (sizeX * sizeY); + for(i = 0; i < sizeX * sizeY; ++i) + mask.Tab[i] = zoneBankElement->getMask()[i]; + mask.w = sizeX; + mask.h = sizeY; + mask.rotFlip (rot, flip); + + for (j = 0; j < mask.h; ++j) + for (i = 0; i < mask.w; ++i) + if (mask.Tab[i + j * mask.w]) + { + set(x + deltaX + i, y + deltaY + j, 0, 0, STRING_UNUSED, true); + setRot(x + deltaX + i, y + deltaY + j, 0); + setFlip(x + deltaX + i, y + deltaY + j, 0); + if (pUpdate != NULL) + { + pUpdate->add(this, x + deltaX + i, y + deltaY + j, ""); + } + } + if (!transition) + reduceMin (); + } + else + { + if ((x < zoneRegion.getMinX()) || (x > zoneRegion.getMaxX()) || + (y < zoneRegion.getMinY()) || (y > zoneRegion.getMaxY())) + return; + + ZonePosition zonePosTemp(x, y, m_regionId); + LigoData dataZoneTemp; + m_zoneBuilder->ligoData(dataZoneTemp, zonePosTemp); + LigoData dataZoneTempOriginal = dataZoneTemp; + + dataZoneTemp.zoneName = STRING_UNUSED; + dataZoneTemp.posX = 0; + dataZoneTemp.posY = 0; + + for (uint32 i = 0; i < 4; ++i) + { + dataZoneTemp.sharingMatNames[i] = STRING_UNUSED; + dataZoneTemp.sharingCutEdges[i] = 0; + } + + // Add modification landscape + if (dataZoneTempOriginal != dataZoneTemp) + m_zoneBuilder->actionLigoTile(dataZoneTemp, zonePosTemp); + + } +} + +void BuilderZoneRegion::move (sint32 x, sint32 y) +{ + m_zoneBuilder->actionLigoMove(m_regionId, x, y); +} + +uint32 BuilderZoneRegion::countZones () +{ + const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion(); + sint32 x, y; + + uint32 counter = 0; + + for (y = zoneRegion.getMinY (); y <= zoneRegion.getMaxY (); ++y) + for (x = zoneRegion.getMinX (); x <= zoneRegion.getMaxX (); ++x) + if (zoneRegion.getName (x, y) != STRING_UNUSED) + ++counter; + + return counter; +} + +void BuilderZoneRegion::set(sint32 x, sint32 y, sint32 posX, sint32 posY, + const std::string &zoneName, bool transition) +{ + const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion(); + + // Do we need to resize ? + if ((x < zoneRegion.getMinX()) || (x > zoneRegion.getMaxX()) || + (y < zoneRegion.getMinY()) || (y > zoneRegion.getMaxY())) + { + sint32 newMinX = (x < zoneRegion.getMinX() ? x: zoneRegion.getMinX()), newMinY = (y < zoneRegion.getMinY() ? y: zoneRegion.getMinY()); + sint32 newMaxX = (x > zoneRegion.getMaxX() ? x: zoneRegion.getMaxX()), newMaxY = (y > zoneRegion.getMaxY() ? y: zoneRegion.getMaxY()); + + resize(newMinX, newMaxX, newMinY, newMaxY); + } + + ZonePosition zonePosTemp(x, y, m_regionId); + LigoData dataZoneTemp; + m_zoneBuilder->ligoData(dataZoneTemp, zonePosTemp); + LigoData dataZoneTempOriginal = dataZoneTemp; + + dataZoneTemp.zoneName = zoneName; + dataZoneTemp.posX = (uint8)posX; + dataZoneTemp.posY = (uint8)posY; + + if (!transition) + { + NLLIGO::CZoneBankElement *zoneBankElem = m_zoneBuilder->getZoneBank().getElementByZoneName(zoneName); + if (zoneBankElem == NULL) + return; + + const std::string &matName = zoneBankElem->getCategory ("material"); + if (matName == STRING_NO_CAT_TYPE) + return; + for (uint32 i = 0; i < 4; ++i) + { + dataZoneTemp.sharingMatNames[i] = matName; + dataZoneTemp.sharingCutEdges[i] = 0; + } + + // Add modification landscape + if (dataZoneTempOriginal != dataZoneTemp) + m_zoneBuilder->actionLigoTile(dataZoneTemp, zonePosTemp); + + BuilderZoneRegion *builderZoneRegion = this; + ZonePosition zonePosU; + if (m_zoneBuilder->getZoneAmongRegions(zonePosU, builderZoneRegion, x - 1, y - 1)) + { + LigoData data; + m_zoneBuilder->ligoData(data, zonePosU); + if (data.sharingMatNames[3] != matName) + { + data.sharingMatNames[3] = matName; + + // Add modification landscape + m_zoneBuilder->actionLigoTile(data, zonePosU); + } + } + builderZoneRegion = this; + if (m_zoneBuilder->getZoneAmongRegions(zonePosU, builderZoneRegion, x, y - 1)) + { + LigoData data; + m_zoneBuilder->ligoData(data, zonePosU); + if ((data.sharingMatNames[2] != matName) || (data.sharingMatNames[3] != matName)) + { + data.sharingMatNames[2] = matName; + data.sharingMatNames[3] = matName; + + // Add modification landscape + m_zoneBuilder->actionLigoTile(data, zonePosU); + } + } + builderZoneRegion = this; + if (m_zoneBuilder->getZoneAmongRegions(zonePosU, builderZoneRegion, x + 1, y - 1)) + { + LigoData data; + m_zoneBuilder->ligoData(data, zonePosU); + if (data.sharingMatNames[2] != matName) + { + data.sharingMatNames[2] = matName; + + // Add modification landscape + m_zoneBuilder->actionLigoTile(data, zonePosU); + } + } + builderZoneRegion = this; + if (m_zoneBuilder->getZoneAmongRegions(zonePosU, builderZoneRegion, x - 1, y)) + { + LigoData data; + m_zoneBuilder->ligoData(data, zonePosU); + if ((data.sharingMatNames[1] != matName) || (data.sharingMatNames[3] != matName)) + { + data.sharingMatNames[1] = matName; + data.sharingMatNames[3] = matName; + + // Add modification landscape + m_zoneBuilder->actionLigoTile(data, zonePosU); + } + } + builderZoneRegion = this; + if (m_zoneBuilder->getZoneAmongRegions(zonePosU, builderZoneRegion, x + 1, y)) + { + LigoData data; + m_zoneBuilder->ligoData(data, zonePosU); + if ((data.sharingMatNames[0] != matName) || (data.sharingMatNames[2] != matName)) + { + data.sharingMatNames[0] = matName; + data.sharingMatNames[2] = matName; + + // Add modification landscape + m_zoneBuilder->actionLigoTile(data, zonePosU); + } + } + builderZoneRegion = this; + if (m_zoneBuilder->getZoneAmongRegions(zonePosU, builderZoneRegion, x - 1, y + 1)) + { + LigoData data; + m_zoneBuilder->ligoData(data, zonePosU); + if (data.sharingMatNames[1] != matName) + { + data.sharingMatNames[1] = matName; + + // Add modification landscape + m_zoneBuilder->actionLigoTile(data, zonePosU); + } + } + builderZoneRegion = this; + if (m_zoneBuilder->getZoneAmongRegions(zonePosU, builderZoneRegion, x, y + 1)) + { + LigoData data; + m_zoneBuilder->ligoData(data, zonePosU); + if ((data.sharingMatNames[0] != matName) || (data.sharingMatNames[1] != matName)) + { + data.sharingMatNames[0] = matName; + data.sharingMatNames[1] = matName; + + // Add modification landscape + m_zoneBuilder->actionLigoTile(data, zonePosU); + } + } + builderZoneRegion = this; + if (m_zoneBuilder->getZoneAmongRegions(zonePosU, builderZoneRegion, x + 1, y + 1)) + { + LigoData data; + m_zoneBuilder->ligoData(data, zonePosU); + if (data.sharingMatNames[0] != matName) + { + data.sharingMatNames[0] = matName; + + // Add modification landscape + m_zoneBuilder->actionLigoTile(data, zonePosU); + } + } + } + else + { + // Add modification landscape + if (dataZoneTempOriginal != dataZoneTemp) + m_zoneBuilder->actionLigoTile(dataZoneTemp, zonePosTemp); + } +} + +void BuilderZoneRegion::setRot (sint32 x, sint32 y, uint8 rot) +{ + ZonePosition zonePosTemp(x, y, m_regionId); + LigoData dataZoneTemp; + m_zoneBuilder->ligoData(dataZoneTemp, zonePosTemp); + if (dataZoneTemp.rot != rot) + { + dataZoneTemp.rot = rot; + + // Add modification landscape + m_zoneBuilder->actionLigoTile(dataZoneTemp, zonePosTemp); + } +} + +void BuilderZoneRegion::setFlip(sint32 x, sint32 y, uint8 flip) +{ + ZonePosition zonePosTemp(x, y, m_regionId); + LigoData dataZoneTemp; + m_zoneBuilder->ligoData(dataZoneTemp, zonePosTemp); + if (dataZoneTemp.flip != flip) + { + dataZoneTemp.flip = flip; + + // Add modification landscape + m_zoneBuilder->actionLigoTile(dataZoneTemp, zonePosTemp); + } +} + + +void BuilderZoneRegion::reduceMin () +{ + const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion(); + sint32 i, j; + + sint32 newMinX = zoneRegion.getMinX(), newMinY = zoneRegion.getMinY (); + sint32 newMaxX = zoneRegion.getMaxX(), newMaxY = zoneRegion.getMaxY (); + bool bCanSuppr; + + // Reduce the MinY + while (true) + { + if (newMinY == newMaxY) + break; + j = newMinY; + bCanSuppr = true; + for (i = newMinX; i <= newMaxX; ++i) + { + std::string str = zoneRegion.getName (i, j) ; + if (!str.empty() && (str != STRING_UNUSED)) + { + bCanSuppr = false; + break; + } + } + if (bCanSuppr) + ++newMinY; + else + break; + } + + // Reduce the MaxY + while (true) + { + if (newMinY == newMaxY) + break; + j = newMaxY; + bCanSuppr = true; + for (i = newMinX; i <= newMaxX; ++i) + { + std::string str = zoneRegion.getName (i, j) ; + if (!str.empty() && (str != STRING_UNUSED)) + { + bCanSuppr = false; + break; + } + } + if (bCanSuppr) + --newMaxY; + else + break; + } + + // Reduce the MinX + while (true) + { + if (newMinX == newMaxX) + break; + i = newMinX; + bCanSuppr = true; + for (j = newMinY; j <= newMaxY; ++j) + { + std::string str = zoneRegion.getName (i, j) ; + if (!str.empty() && (str != STRING_UNUSED)) + { + bCanSuppr = false; + break; + } + } + if (bCanSuppr) + ++newMinX; + else + break; + } + + // Reduce the MaxX + while (true) + { + if (newMinX == newMaxX) + break; + i = newMaxX; + bCanSuppr = true; + for (j = newMinY; j <= newMaxY; ++j) + { + std::string str = zoneRegion.getName (i, j) ; + if (!str.empty() && (str != STRING_UNUSED)) + { + bCanSuppr = false; + break; + } + } + if (bCanSuppr) + --newMaxX; + else + break; + } + + if ((newMinX != zoneRegion.getMinX ()) || + (newMinY != zoneRegion.getMinY ()) || + (newMaxX != zoneRegion.getMaxX ()) || + (newMaxY != zoneRegion.getMaxY ())) + { + resize(newMinX, newMaxX, newMinY, newMaxY); + } +} + +uint BuilderZoneRegion::getRegionId() const +{ + return m_regionId; +} + +void BuilderZoneRegion::resize (sint32 newMinX, sint32 newMaxX, sint32 newMinY, sint32 newMaxY) +{ + const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion(); + if ((zoneRegion.getMinX ()!= newMinX) || + (zoneRegion.getMaxX ()!= newMaxX) || + (zoneRegion.getMinY ()!= newMinY) || + (zoneRegion.getMaxY ()!= newMaxY)) + { + m_zoneBuilder->actionLigoResize(m_regionId, newMinX, newMaxX, newMinY, newMaxY); + } +} + } /* namespace LandscapeEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.h index 158c72715..7322e47b6 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.h @@ -1,33 +1,101 @@ -// Object Viewer Qt - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// Copyright (C) 2011 Dzmitry Kamiahin -// -// 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 . - -#ifndef BUILDER_ZONE_REGION_H -#define BUILDER_ZONE_REGION_H - -// Project includes - -// NeL includes -#include - -// Qt includes - -namespace LandscapeEditor -{ - -} /* namespace LandscapeEditor */ - -#endif // BUILDER_ZONE_REGION_H +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +#ifndef BUILDER_ZONE_REGION_H +#define BUILDER_ZONE_REGION_H + +// Project includes + +// NeL includes +#include +#include + +// STL includes +#include +#include +#include + +// 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, std::string &error); + 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 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 &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 m_matTree; + + bool m_firstInit; +}; + +} /* namespace LandscapeEditor */ + +#endif // BUILDER_ZONE_REGION_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp index 84d59ba8d..95f030631 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp @@ -62,54 +62,111 @@ void NewLandscapeCommand::redo() { } -AddLigoTileCommand::AddLigoTileCommand(const LigoData &data, LandscapeScene *scene, QUndoCommand *parent) +LigoTileCommand::LigoTileCommand(const LigoData &data, const ZonePosition &zonePos, + ZoneBuilder *zoneBuilder, LandscapeScene *scene, + QUndoCommand *parent) : QUndoCommand(parent), - m_item(0), + m_zoneBuilder(zoneBuilder), m_scene(scene) { - m_ligoData = data; + // Backup position + m_zonePos = zonePos; + + // Backup new data + m_newLigoData = data; + + // Backup old data + m_zoneBuilder->ligoData(m_oldLigoData, m_zonePos); } -AddLigoTileCommand::~AddLigoTileCommand() +LigoTileCommand::~LigoTileCommand() { } -void AddLigoTileCommand::undo() +void LigoTileCommand::undo () { - m_scene->removeItem(m_item); - delete m_item; - m_item = 0; + m_zoneBuilder->setLigoData(m_oldLigoData, m_zonePos); + m_scene->createZoneItem(m_oldLigoData, m_zonePos); } -void AddLigoTileCommand::redo() +void LigoTileCommand::redo () { - m_item = m_scene->createZoneItem(m_ligoData); - setText(QObject::tr("Add tile(%1, %2)").arg(m_ligoData.PosX).arg(m_ligoData.PosY)); + m_zoneBuilder->setLigoData(m_newLigoData, m_zonePos); + m_scene->createZoneItem(m_newLigoData, m_zonePos); } -DelLigoTileCommand::DelLigoTileCommand(const LigoData &data, LandscapeScene *scene, QUndoCommand *parent) +LigoResizeCommand::LigoResizeCommand(int index, sint32 newMinX, sint32 newMaxX, + sint32 newMinY, sint32 newMaxY, ZoneBuilder *zoneBuilder, + QUndoCommand *parent) : QUndoCommand(parent), - m_item(0), - m_scene(scene) + m_zoneBuilder(zoneBuilder) { - m_ligoData = data; + 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)->zoneRegion(); } -DelLigoTileCommand::~DelLigoTileCommand() +LigoResizeCommand::~LigoResizeCommand() { } -void DelLigoTileCommand::undo() +void LigoResizeCommand::undo () { - m_item = m_scene->createZoneItem(m_ligoData); + // Restore old region zone + m_zoneBuilder->zoneRegion(m_index)->setZoneRegion(m_oldZoneRegion); } -void DelLigoTileCommand::redo() +void LigoResizeCommand::redo () { - m_item = m_scene->itemAt(m_ligoData.PosX * m_scene->cellSize(), m_ligoData.PosY * m_scene->cellSize()); - delete m_item; - m_item = 0; - setText(QObject::tr("Del tile(%1, %2)").arg(m_ligoData.PosX).arg(m_ligoData.PosY)); + // Get the zone region + NLLIGO::CZoneRegion ®ion = m_zoneBuilder->zoneRegion(m_index)->zoneRegion(); + + sint32 i, j; + std::vector 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 */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h index 7bbd1bd96..e7a39d8b1 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h @@ -56,36 +56,64 @@ public: private: }; -class AddLigoTileCommand: public QUndoCommand +// Modify the landscape +class LigoTileCommand: public QUndoCommand { public: - AddLigoTileCommand(const LigoData &data, LandscapeScene *scene, QUndoCommand *parent = 0); - virtual ~AddLigoTileCommand(); + LigoTileCommand(const LigoData &data, const ZonePosition &zonePos, + ZoneBuilder *zoneBuilder, LandscapeScene *scene, + QUndoCommand *parent = 0); + virtual ~LigoTileCommand(); virtual void undo(); virtual void redo(); private: - - LigoData m_ligoData; - QGraphicsItem *m_item; + ZonePosition m_zonePos; + LigoData m_newLigoData; + LigoData m_oldLigoData; + ZoneBuilder *m_zoneBuilder; LandscapeScene *m_scene; }; +/* +// Move the landscape +class LigoMoveCommand: public QUndoCommand +{ +public: -class DelLigoTileCommand: public QUndoCommand + 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: - DelLigoTileCommand(const LigoData &data, LandscapeScene *scene, QUndoCommand *parent = 0); - virtual ~DelLigoTileCommand(); + 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: - - LigoData m_ligoData; - QGraphicsItem *m_item; - LandscapeScene *m_scene; + int m_index; + sint32 m_newMinX; + sint32 m_newMaxX; + sint32 m_newMinY; + sint32 m_newMaxY; + NLLIGO::CZoneRegion m_oldZoneRegion; + ZoneBuilder *m_zoneBuilder; }; } /* namespace LandscapeEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp index 5ec3f6196..0c38adbf6 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp @@ -19,6 +19,7 @@ #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" @@ -45,12 +46,14 @@ LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent) m_ui.setupUi(this); m_undoStack = new QUndoStack(this); - m_zoneBuilder = new ZoneBuilder(); - m_zoneBuilder->init("e:/-nel-/install/continents/newbieland", false); + m_landscapeScene = new LandscapeScene(this); + + m_zoneBuilder = new ZoneBuilder(m_ui.zoneListWidget, m_landscapeScene, m_undoStack); + m_zoneBuilder->init("e:/-nel-/install/continents/newbieland", true); m_ui.zoneListWidget->setZoneBuilder(m_zoneBuilder); m_ui.zoneListWidget->updateUi(); - m_landscapeScene = new LandscapeScene(m_undoStack, m_ui.zoneListWidget, m_zoneBuilder, this); + m_landscapeScene->setZoneBuilder(m_zoneBuilder); m_ui.graphicsView->setScene(m_landscapeScene); //m_ui.graphicsView->setViewport(new QGLWidget(QGLFormat(QGL::DoubleBuffer))); m_ui.graphicsView->setViewport(new QGLWidget(QGLFormat(QGL::DoubleBuffer | QGL::SampleBuffers))); @@ -88,11 +91,14 @@ void LandscapeEditorWindow::open() _lastDir = QFileInfo(list.front()).absolutePath(); Q_FOREACH(QString fileName, fileNames) { - m_zoneRegionEditor.load(fileName.toStdString()); - m_landscapeScene->processZoneRegion(m_zoneRegionEditor.zoneRegion()); - m_landscapeScene->setCurrentZoneRegion(&m_zoneRegionEditor.zoneRegion()); - m_ui.graphicsView->centerOn(m_zoneRegionEditor.zoneRegion().getMinX() * m_landscapeScene->cellSize(), - abs(m_zoneRegionEditor.zoneRegion().getMinY()) * m_landscapeScene->cellSize()); + int id = m_zoneBuilder->createZoneRegion(); + ZoneRegionEditor *zoneRegion = m_zoneBuilder->zoneRegion(id); + zoneRegion->load(fileName.toStdString()); + m_landscapeScene->processZoneRegion(zoneRegion->zoneRegion()); + m_ui.graphicsView->centerOn(zoneRegion->zoneRegion().getMinX() * m_landscapeScene->cellSize(), + abs(zoneRegion->zoneRegion().getMinY()) * m_landscapeScene->cellSize()); + + m_zoneBuilder->setCurrentZoneRegion(id); } } setCursor(Qt::ArrowCursor); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h index 311a65013..3a35b90f4 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h @@ -20,7 +20,6 @@ // Project includes #include "ui_landscape_editor_window.h" -#include "zone_region_editor.h" // Qt includes #include @@ -55,8 +54,6 @@ private: void readSettings(); void writeSettings(); - ZoneRegionEditor m_zoneRegionEditor; - LandscapeScene *m_landscapeScene; ZoneBuilder *m_zoneBuilder; QUndoStack *m_undoStack; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp index 96ad0879b..3aa2bbc9a 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp @@ -17,9 +17,6 @@ // Project includes #include "landscape_scene.h" -#include "builder_zone.h" -#include "landscape_actions.h" -#include "list_zones_widget.h" // NeL includes #include @@ -32,12 +29,9 @@ namespace LandscapeEditor { -LandscapeScene::LandscapeScene(QUndoStack *undoStack, ListZonesWidget *listZonesWidget, ZoneBuilder *zoneBuilder, QObject *parent) +LandscapeScene::LandscapeScene(QObject *parent) : QGraphicsScene(parent), - m_undoStack(undoStack), - m_listZonesWidget(listZonesWidget), - m_zoneBuilder(zoneBuilder), - m_zoneRegion(0) + m_zoneBuilder(0) { m_cellSize = 160; } @@ -51,20 +45,34 @@ int LandscapeScene::cellSize() const return m_cellSize; } -QGraphicsItem *LandscapeScene::createZoneItem(const LigoData &data) +void LandscapeScene::setZoneBuilder(ZoneBuilder *zoneBuilder) { + m_zoneBuilder = zoneBuilder; +} + +QGraphicsItem *LandscapeScene::createZoneItem(const LigoData &data, const ZonePosition &zonePos) +{ + if (data.zoneName == STRING_UNUSED) + return createEmptyZoneItem(zonePos); + + if ((m_zoneBuilder == 0) || (data.zoneName.empty()) || + (data.posX != 0) || (data.posY != 0)) + return 0; + + checkUnderZone(data, zonePos); + // Get image from pixmap database - QPixmap *pixmap = m_zoneBuilder->pixmapDatabase()->pixmap(QString(data.ZoneName.c_str())); + 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); + matrix.rotate(-data.rot * 90.0); QGraphicsPixmapItem *item; - if (data.Flip == 0) + if (data.flip == 0) { item = new QGraphicsPixmapItem(pixmap->transformed(matrix, Qt::SmoothTransformation), 0, this); } @@ -79,135 +87,156 @@ QGraphicsItem *LandscapeScene::createZoneItem(const LigoData &data) item->setTransformationMode(Qt::SmoothTransformation); // Set position graphics item with offset for large piece - NLLIGO::CZoneBankElement *zoneBankItem = m_zoneBuilder->getZoneBank().getElementByZoneName(data.ZoneName); - item->setPos(data.PosX * m_cellSize, (abs(data.PosY) - zoneBankItem->getSizeY() + 1) * m_cellSize); + NLLIGO::CZoneBankElement *zoneBankItem = m_zoneBuilder->getZoneBank().getElementByZoneName(data.zoneName); + item->setPos(zonePos.x * m_cellSize, (abs(zonePos.y) - zoneBankItem->getSizeY() + 1) * m_cellSize); // The size graphics item should be equal or proportional m_cellSize - item->setScale(m_cellSize / 256.0); + item->setScale(float(m_cellSize) / m_zoneBuilder->pixmapDatabase()->textureSize()); + + return item; +} + +QGraphicsItem *LandscapeScene::createEmptyZoneItem(const ZonePosition &zonePos) +{ + if (m_zoneBuilder == 0) + return 0; + + deleteZoneItem(zonePos); + + // Get image from pixmap database + QPixmap *pixmap = m_zoneBuilder->pixmapDatabase()->pixmap(QString(STRING_UNUSED)); + if (pixmap == 0) + return 0; - // add debug info - QGraphicsSimpleTextItem *itemText = addSimpleText(QString("%1,%2 R-%3 F-%4"). - arg(data.PosX).arg(data.PosY). - arg(data.Rot * 90.0). - arg(data.Flip), - QFont("Helvetica [Cronyx]", 14)); + QGraphicsPixmapItem *item = new QGraphicsPixmapItem(*pixmap, 0, this); - itemText->setZValue(2); - itemText->setPos(data.PosX * m_cellSize + 10, (abs(data.PosY) - zoneBankItem->getSizeY() + 1) * m_cellSize + 10); - itemText->setBrush(QBrush(Qt::white)); + // 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()); return item; } +void LandscapeScene::deleteZoneItem(const ZonePosition &zonePos) +{ + QGraphicsItem *item = itemAt(zonePos.x * m_cellSize, abs(zonePos.y) * m_cellSize); + if (item != 0) + { + removeItem(item); + delete item; + } +} + void LandscapeScene::processZoneRegion(const NLLIGO::CZoneRegion &zoneRegion) { for (sint32 i = zoneRegion.getMinX(); i <= zoneRegion.getMaxX(); ++i) { for (sint32 j = zoneRegion.getMinY(); j <= zoneRegion.getMaxY(); ++j) { + nlinfo(QString("%1 %2 %3").arg(i).arg(j).arg(zoneRegion.getName(i, j).c_str()).toStdString().c_str()); std::string zoneName = zoneRegion.getName(i, j); - if ((!zoneName.empty()) && - (zoneName != STRING_UNUSED) && - (zoneRegion.getPosX(i, j) == 0) && - (zoneRegion.getPosY(i, j) == 0)) + if (zoneName == STRING_UNUSED) + { + ZonePosition zonePos(i, j, -1); + QGraphicsItem *item = createEmptyZoneItem(zonePos); + } + else if (!zoneName.empty()) { LigoData data; - data.PosX = i; - data.PosY = j; - data.ZoneName = zoneName; - data.Rot = zoneRegion.getRot(i, j); - data.Flip = zoneRegion.getFlip(i, j); - QGraphicsItem *item = createZoneItem(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 = createZoneItem(data, zonePos); } } } } -void LandscapeScene::setCurrentZoneRegion(NLLIGO::CZoneRegion *zoneRegion) -{ - m_zoneRegion = zoneRegion; -} - void LandscapeScene::snapshot(const QString &fileName, int sizeSource) { - if (m_zoneRegion == 0) - return; + /* if (m_zoneRegion == 0) + return; - sint32 regionMinX = m_zoneRegion->getMinX(); - sint32 regionMaxX = m_zoneRegion->getMaxX(); - sint32 regionMinY = m_zoneRegion->getMinY(); - sint32 regionMaxY = m_zoneRegion->getMaxY(); + sint32 regionMinX = m_zoneRegion->getMinX(); + sint32 regionMaxX = m_zoneRegion->getMaxX(); + sint32 regionMinY = m_zoneRegion->getMinY(); + sint32 regionMaxY = m_zoneRegion->getMaxY(); - int regionWidth = (regionMaxX - regionMinX + 1); - int regionHeight = (regionMaxY - regionMinY + 1); + int regionWidth = (regionMaxX - regionMinX + 1); + int regionHeight = (regionMaxY - regionMinY + 1); - snapshot(fileName, regionWidth * sizeSource, regionHeight * sizeSource); + snapshot(fileName, regionWidth * sizeSource, regionHeight * sizeSource); + */ } void LandscapeScene::snapshot(const QString &fileName, int width, int height) { - if (m_zoneRegion == 0) + if (m_zoneBuilder == 0) return; - sint32 regionMinX = m_zoneRegion->getMinX(); - sint32 regionMaxX = m_zoneRegion->getMaxX(); - sint32 regionMinY = m_zoneRegion->getMinY(); - sint32 regionMaxY = m_zoneRegion->getMaxY(); + /* if (m_zoneRegion == 0) + return; - int regionWidth = (regionMaxX - regionMinX + 1); - int regionHeight = (regionMaxY - regionMinY + 1); + sint32 regionMinX = m_zoneRegion->getMinX(); + sint32 regionMaxX = m_zoneRegion->getMaxX(); + sint32 regionMinY = m_zoneRegion->getMinY(); + sint32 regionMaxY = m_zoneRegion->getMaxY(); - QImage image(width, height, QImage::Format_RGB888); - QPainter painter(&image); - painter.setRenderHint(QPainter::Antialiasing, true); + int regionWidth = (regionMaxX - regionMinX + 1); + int regionHeight = (regionMaxY - regionMinY + 1); - // add white background - painter.setBrush(QBrush(Qt::white)); - painter.setPen(Qt::NoPen); - painter.drawRect(0, 0, width, height); + QImage image(width, height, QImage::Format_RGB888); + QPainter painter(&image); + painter.setRenderHint(QPainter::Antialiasing, true); - render(&painter, QRectF(0, 0, width, height), - QRectF(regionMinX * m_cellSize, abs(regionMaxY) * m_cellSize, regionWidth * m_cellSize, regionHeight * m_cellSize)); + // add white background + painter.setBrush(QBrush(Qt::white)); + painter.setPen(Qt::NoPen); + painter.drawRect(0, 0, width, height); - image.save(fileName); + render(&painter, QRectF(0, 0, width, height), + QRectF(regionMinX * m_cellSize, abs(regionMaxY) * m_cellSize, regionWidth * m_cellSize, regionHeight * m_cellSize)); + image.save(fileName); + */ } void LandscapeScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) { + if (m_zoneBuilder == 0) + return; + qreal x = mouseEvent->scenePos().rx(); qreal y = mouseEvent->scenePos().ry(); if ((x < 0) || (y < 0)) return; - if (mouseEvent->button() == Qt::LeftButton) - { - // Add new zone brick - LigoData ligoData = m_listZonesWidget->currentLigoData(); - if (ligoData.ZoneName == "") - return; - - ligoData.PosX = int(floor(x / m_cellSize)); - ligoData.PosY = int(-floor(y / m_cellSize)); + sint32 posX = sint32(floor(x / m_cellSize)); + sint32 posY = sint32(-floor(y / m_cellSize)); - AddLigoTileCommand *action = new AddLigoTileCommand(ligoData, this); - m_undoStack->push(action); - } + if (mouseEvent->button() == Qt::LeftButton) + m_zoneBuilder->addZone(posX, posY); + else if (mouseEvent->button() == Qt::RightButton) + m_zoneBuilder->delZone(posX, posY); - /*if (mouseEvent->button() == Qt::RightButton) - { - // Delete zone brick - LigoData ligoData; - - ligoData.PosX = int(floor(x / m_cellSize)); - ligoData.PosY = int(floor(y / m_cellSize)); - ligoData.ZoneName = m_zoneRegion->getName(ligoData.PosX, -ligoData.PosY); - ligoData.Flip = m_zoneRegion->getFlip(ligoData.PosX, -ligoData.PosY); - ligoData.Rot = m_zoneRegion->getRot(ligoData.PosX, -ligoData.PosY); - DelLigoTileCommand *action = new DelLigoTileCommand(ligoData, this); - m_undoStack->push(action); - }*/ QGraphicsScene::mousePressEvent(mouseEvent); } +void LandscapeScene::checkUnderZone(const LigoData &data, const ZonePosition &zonePos) +{ +// NLLIGO::CZoneBankElement *zoneBankItem = m_zoneBuilder->getZoneBank().getElementByZoneName(data.zoneName); +// uint8 sizeX = zoneBankItem->getSizeX(); +// uint8 sizeY = zoneBankItem->getSizeY(); +// std::vector &mask = zoneBankItem->getMask(); + deleteZoneItem(zonePos); +} + } /* namespace LandscapeEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h index 2af45bf4b..ea314faac 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h @@ -19,6 +19,8 @@ #define LANDSCAPE_SCENE_H // Project includes +#include "zone_region_editor.h" +#include "builder_zone.h" // NeL includes #include @@ -26,54 +28,25 @@ // Qt includes #include #include -#include namespace LandscapeEditor { -class ZoneBuilder; -class ListZonesWidget; - -// Data -struct LigoData -{ - sint32 PosX; - sint32 PosY; - uint8 Rot; - uint8 Flip; - std::string ZoneName; - std::string SharingMatNames[4]; - uint8 SharingCutEdges[4]; - 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 LandscapeScene : public QGraphicsScene { Q_OBJECT public: - LandscapeScene(QUndoStack *undoStack, ListZonesWidget *listZonesWidget, ZoneBuilder *zoneBuilder, QObject *parent = 0); + LandscapeScene(QObject *parent = 0); virtual ~LandscapeScene(); int cellSize() const; + void setZoneBuilder(ZoneBuilder *zoneBuilder); - QGraphicsItem *createZoneItem(const LigoData &data); + QGraphicsItem *createZoneItem(const LigoData &data, const ZonePosition &zonePos); + QGraphicsItem *createEmptyZoneItem(const ZonePosition &zonePos); + void deleteZoneItem(const ZonePosition &zonePos); void processZoneRegion(const NLLIGO::CZoneRegion &zoneRegion); - void setCurrentZoneRegion(NLLIGO::CZoneRegion *zoneRegion); void snapshot(const QString &fileName, int sizeSource); void snapshot(const QString &fileName, int width, int height); @@ -82,12 +55,10 @@ protected: virtual void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent); private: + void checkUnderZone(const LigoData &data, const ZonePosition &zonePos); int m_cellSize; - ListZonesWidget *m_listZonesWidget; - QUndoStack *m_undoStack; ZoneBuilder *m_zoneBuilder; - NLLIGO::CZoneRegion *m_zoneRegion; }; } /* namespace LandscapeEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp index 66d31479b..7ce3f5421 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp @@ -18,6 +18,7 @@ // Project includes #include "list_zones_widget.h" #include "list_zones_model.h" +#include "builder_zone.h" // NeL includes #include @@ -100,17 +101,34 @@ void ListZonesWidget::updateUi() m_listZonesModel->rebuildModel(m_zoneBuilder->pixmapDatabase()); } -LigoData ListZonesWidget::currentLigoData() const +QString ListZonesWidget::currentZoneName() const { - LigoData ligoData; - ligoData.ZoneName = ""; + QString zoneName = ""; QModelIndex index = m_ui.listView->currentIndex(); if (index.isValid()) - ligoData.ZoneName = index.data().toString().toStdString(); + zoneName = index.data().toString(); - ligoData.Rot = m_ui.rotComboBox->currentIndex(); - ligoData.Flip = m_ui.flipComboBox->currentIndex(); - return ligoData; + return zoneName; +} + +int ListZonesWidget::currentRot() const +{ + return m_ui.rotComboBox->currentIndex(); +} + +int ListZonesWidget::currentFlip() const +{ + return m_ui.flipComboBox->currentIndex(); +} + +bool ListZonesWidget::isNotPropogate() const +{ + return m_ui.propogateCheckBox->isChecked(); +} + +bool ListZonesWidget::isForce() const +{ + return m_ui.forceCheckBox->isChecked(); } void ListZonesWidget::setZoneBuilder(ZoneBuilder *zoneBuilder) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h index 8ad5d4c25..c35e7b0fa 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h @@ -20,8 +20,6 @@ // Project includes #include "ui_list_zones_widget.h" -#include "builder_zone.h" -#include "landscape_scene.h" // NeL includes @@ -30,6 +28,7 @@ namespace LandscapeEditor { class ListZonesModel; +class ZoneBuilder; /** @class ZoneListWidget @@ -46,7 +45,11 @@ public: void updateUi(); void setZoneBuilder(ZoneBuilder *zoneBuilder); - LigoData currentLigoData() const; + QString currentZoneName() const; + int currentRot() const; + int currentFlip() const; + bool isNotPropogate() const; + bool isForce() const; Q_SIGNALS: private Q_SLOTS: diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.cpp index a3f109ada..045b342fd 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.cpp @@ -30,6 +30,23 @@ namespace LandscapeEditor { +LigoData::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; +} + ZoneRegionEditor::ZoneRegionEditor() { m_fileName = ""; @@ -111,9 +128,58 @@ void ZoneRegionEditor::setFileName(const std::string &fileName) m_fileName = fileName; } +void ZoneRegionEditor::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 ZoneRegionEditor::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 &ZoneRegionEditor::zoneRegion() { return m_zoneRegion; } +void ZoneRegionEditor::setZoneRegion(const NLLIGO::CZoneRegion &zoneRegion) +{ + m_zoneRegion = zoneRegion; +} + } /* namespace LandscapeEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.h index fd53d5483..50fab0e58 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.h @@ -32,6 +32,36 @@ namespace LandscapeEditor { +struct LigoData +{ + uint8 posX; + uint8 posY; + uint8 rot; + uint8 flip; + std::string zoneName; + std::string sharingMatNames[4]; + uint8 sharingCutEdges[4]; + + LigoData(); + + 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 ZoneRegionEditor { public: @@ -44,11 +74,17 @@ public: // Save landscape data to file bool save(); + void ligoData(LigoData &data, const sint32 x, const sint32 y); + + void setLigoData(const LigoData &data, const sint32 x, const sint32 y); + // Set file name void setFileName(const std::string &fileName); NLLIGO::CZoneRegion &zoneRegion(); + void setZoneRegion(const NLLIGO::CZoneRegion &zoneRegion); + private: bool m_modified; From b390026b76f2ba99ddeef7b7b0c8d0b4b62ea25b Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Thu, 30 Jun 2011 00:25:43 +0300 Subject: [PATCH 09/89] Changed: #1301 Improved 2d render. Fixed adding empty undo/redo operations in command list, improved performance when adding new zones. --HG-- branch : gsoc2011-worldeditorqt --- .../plugins/landscape_editor/builder_zone.cpp | 50 ++++++++++-- .../plugins/landscape_editor/builder_zone.h | 15 +++- .../landscape_editor/landscape_actions.cpp | 70 +++++++++++++++- .../landscape_editor/landscape_actions.h | 35 ++++++++ .../landscape_editor_window.cpp | 17 +++- .../landscape_editor_window.h | 1 + .../landscape_editor_window.ui | 6 ++ .../landscape_editor/landscape_scene.cpp | 79 +++++++++++++++---- .../landscape_editor/landscape_scene.h | 11 ++- .../landscape_editor/landscape_view.cpp | 2 + .../landscape_editor/zone_region_editor.cpp | 70 +++++++++++----- .../landscape_editor/zone_region_editor.h | 27 ++----- 12 files changed, 310 insertions(+), 73 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp index 8271fe37c..0e00d72be 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp @@ -167,18 +167,22 @@ bool ZoneBuilder::init(const QString &pathName, bool makeAZone) void ZoneBuilder::actionLigoTile(const LigoData &data, const ZonePosition &zonePos) { + 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) { + 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) { + 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)); } @@ -201,7 +205,11 @@ void ZoneBuilder::addZone(sint32 posX, sint32 posY) NLLIGO::CZoneBankElement *zoneBankElement = getZoneBank().getElementByZoneName(zoneName); - m_undoStack->beginMacro(QString("Add zone %1,%2").arg(posX).arg(posY)); + m_titleAction = QString("Add zone %1,%2").arg(posX).arg(posY); + m_createdAction = false; + m_zonePositionList.clear(); + + nlinfo("---------"); if (m_listZonesWidget->isForce()) { builderZoneRegion->addForce(posX, posY, rot, flip, zoneBankElement); @@ -213,7 +221,7 @@ void ZoneBuilder::addZone(sint32 posX, sint32 posY) else builderZoneRegion->add(posX, posY, rot, flip, zoneBankElement); } - m_undoStack->endMacro(); + checkEndMacro(); } void ZoneBuilder::addTransition(const sint32 posX, const sint32 posY) @@ -225,17 +233,20 @@ void ZoneBuilder::delZone(const sint32 posX, const sint32 posY) if (m_builderZoneRegions.empty()) return; - m_undoStack->beginMacro(QString("Del zone %1,%2").arg(posX).arg(posY)); + m_titleAction = QString("Del zone %1,%2").arg(posX).arg(posY); + m_createdAction = false; + BuilderZoneRegion *builderZoneRegion = m_builderZoneRegions.at(m_currentZoneRegion); std::string error; + nlinfo("---------"); builderZoneRegion->init(this, error); builderZoneRegion->del(posX, posY); - m_undoStack->endMacro(); + checkEndMacro(); } int ZoneBuilder::createZoneRegion() { - ZoneRegionEditor *newZoneRegion = new ZoneRegionEditor(); + ZoneRegionObject *newZoneRegion = new ZoneRegionObject(); m_zoneRegions.push_back(newZoneRegion); if (m_currentZoneRegion == -1) m_currentZoneRegion = m_zoneRegions.indexOf(newZoneRegion); @@ -261,7 +272,7 @@ int ZoneBuilder::currentIdZoneRegion() const return m_currentZoneRegion; } -ZoneRegionEditor *ZoneBuilder::currentZoneRegion() const +ZoneRegionObject *ZoneBuilder::currentZoneRegion() const { return m_zoneRegions.at(m_currentZoneRegion); } @@ -271,7 +282,7 @@ int ZoneBuilder::countZoneRegion() const return m_zoneRegions.size(); } -ZoneRegionEditor *ZoneBuilder::zoneRegion(int id) const +ZoneRegionObject *ZoneBuilder::zoneRegion(int id) const { return m_zoneRegions.at(id); } @@ -399,7 +410,7 @@ void ZoneBuilder::calcMask() bool ZoneBuilder::getZoneAmongRegions (ZonePosition &zonePos, BuilderZoneRegion *builderZoneRegionFrom, sint32 x, sint32 y) { - Q_FOREACH(ZoneRegionEditor *zoneRegion, m_zoneRegions) + Q_FOREACH(ZoneRegionObject *zoneRegion, m_zoneRegions) { const NLLIGO::CZoneRegion ®ion = zoneRegion->zoneRegion(); if ((x < region.getMinX()) || (x > region.getMaxX()) || @@ -424,4 +435,27 @@ bool ZoneBuilder::getZoneAmongRegions (ZonePosition &zonePos, BuilderZoneRegion 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(); + } +} + } /* namespace LandscapeEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h index 54cdb3b73..ecc47976f 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h @@ -42,6 +42,7 @@ namespace LandscapeEditor { class ListZonesWidget; class LandscapeScene; +class UndoScanRegionCommand; // Data struct ZonePosition @@ -134,9 +135,9 @@ public: void deleteZoneRegion(int id); void setCurrentZoneRegion(int id); int currentIdZoneRegion() const; - ZoneRegionEditor *currentZoneRegion() const; + ZoneRegionObject *currentZoneRegion() const; int countZoneRegion() const; - ZoneRegionEditor *zoneRegion(int id) const; + ZoneRegionObject *zoneRegion(int id) const; void ligoData(LigoData &data, const ZonePosition &zonePos); void setLigoData(LigoData &data, const ZonePosition &zonePos); @@ -155,16 +156,24 @@ private: /// Scan ./zoneligos dir and add all *.ligozone files to zoneBank bool initZoneBank (const QString &path); + void checkBeginMacro(); + void checkEndMacro(); + sint32 m_minX, m_maxX, m_minY, m_maxY; std::vector m_zoneMask; QString m_lastPathName; - QList m_zoneRegions; + QList m_zoneRegions; int m_currentZoneRegion; std::vector m_builderZoneRegions; + bool m_createdAction; + QString m_titleAction; + QList m_zonePositionList; + UndoScanRegionCommand *m_undoScanRegionCommand; + PixmapDatabase *m_pixmapDatabase; NLLIGO::CZoneBank m_zoneBank; ListZonesWidget *m_listZonesWidget; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp index 95f030631..8aea79933 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp @@ -86,13 +86,79 @@ LigoTileCommand::~LigoTileCommand() void LigoTileCommand::undo () { m_zoneBuilder->setLigoData(m_oldLigoData, m_zonePos); - m_scene->createZoneItem(m_oldLigoData, m_zonePos); } void LigoTileCommand::redo () { m_zoneBuilder->setLigoData(m_newLigoData, m_zonePos); - m_scene->createZoneItem(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 &zonePositionList) +{ + m_zonePositionList = zonePositionList; +} + +void UndoScanRegionCommand::undo() +{ + for (int i = 0; i < m_zonePositionList.size(); ++i) + m_scene->deleteItemZone(m_zonePositionList.at(i)); + nlinfo("------"); + 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 &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)); + nlinfo("------"); + 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, diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h index e7a39d8b1..c4afcc801 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h @@ -75,6 +75,41 @@ private: 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 &zonePositionList); + virtual void undo(); + virtual void redo(); + +private: + + QList 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 &zonePositionList); + virtual void undo(); + virtual void redo(); + +private: + + QList m_zonePositionList; + ZoneBuilder *m_zoneBuilder; + LandscapeScene *m_scene; +}; + /* // Move the landscape class LigoMoveCommand: public QUndoCommand diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp index 0c38adbf6..facf90264 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp @@ -62,6 +62,7 @@ LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent) 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))); @@ -92,7 +93,7 @@ void LandscapeEditorWindow::open() Q_FOREACH(QString fileName, fileNames) { int id = m_zoneBuilder->createZoneRegion(); - ZoneRegionEditor *zoneRegion = m_zoneBuilder->zoneRegion(id); + ZoneRegionObject *zoneRegion = m_zoneBuilder->zoneRegion(id); zoneRegion->load(fileName.toStdString()); m_landscapeScene->processZoneRegion(zoneRegion->zoneRegion()); m_ui.graphicsView->centerOn(zoneRegion->zoneRegion().getMinX() * m_landscapeScene->cellSize(), @@ -104,6 +105,20 @@ void LandscapeEditorWindow::open() setCursor(Qt::ArrowCursor); } +void LandscapeEditorWindow::save() +{ + ZoneRegionObject *zoneRegion = m_zoneBuilder->currentZoneRegion(); + if (zoneRegion->fileName().empty()) + { + QString fileName = QFileDialog::getSaveFileName(this, + tr("Save NeL Ligo land file"), _lastDir, + tr("NeL Ligo land file (*.land)")); + if (!fileName.isEmpty()) + zoneRegion->setFileName(fileName.toStdString()); + } + zoneRegion->save(); +} + void LandscapeEditorWindow::openProjectSettings() { ProjectSettingsDialog *dialog = new ProjectSettingsDialog(m_zoneBuilder->dataPath(), this); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h index 3a35b90f4..ccfcf2778 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h @@ -43,6 +43,7 @@ public: Q_SIGNALS: public Q_SLOTS: void open(); + void save(); private Q_SLOTS: void openProjectSettings(); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui index 212d0eb13..57eadda73 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui @@ -72,6 +72,7 @@ false + @@ -107,6 +108,11 @@ snapshot + + + Save + + diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp index 3aa2bbc9a..9970032a7 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp @@ -29,8 +29,12 @@ namespace LandscapeEditor { +static const int ZoneName = 0; + LandscapeScene::LandscapeScene(QObject *parent) : QGraphicsScene(parent), + m_mouseX(0.0), + m_mouseY(0.0), m_zoneBuilder(0) { m_cellSize = 160; @@ -50,16 +54,21 @@ void LandscapeScene::setZoneBuilder(ZoneBuilder *zoneBuilder) m_zoneBuilder = zoneBuilder; } -QGraphicsItem *LandscapeScene::createZoneItem(const LigoData &data, const ZonePosition &zonePos) +QGraphicsItem *LandscapeScene::createItemZone(const LigoData &data, const ZonePosition &zonePos) { + nlinfo(QString("%1,%2 (%3,%4)-%7 (%5,%6)").arg(zonePos.x).arg(zonePos.y).arg(data.posX).arg(data.posY).arg(data.rot).arg(data.flip).arg(data.zoneName.c_str()).toStdString().c_str()); + if ((data.zoneName == STRING_OUT_OF_BOUND) || (checkUnderZone(zonePos.x, zonePos.y))) + return 0; + if (data.zoneName == STRING_UNUSED) - return createEmptyZoneItem(zonePos); + return createItemEmptyZone(zonePos); if ((m_zoneBuilder == 0) || (data.zoneName.empty()) || (data.posX != 0) || (data.posY != 0)) return 0; - checkUnderZone(data, 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())); @@ -88,21 +97,27 @@ QGraphicsItem *LandscapeScene::createZoneItem(const LigoData &data, const ZonePo // Set position graphics item with offset for large piece NLLIGO::CZoneBankElement *zoneBankItem = m_zoneBuilder->getZoneBank().getElementByZoneName(data.zoneName); - item->setPos(zonePos.x * m_cellSize, (abs(zonePos.y) - zoneBankItem->getSizeY() + 1) * m_cellSize); + + int delta = zoneBankItem->getSizeY() - 1; + if ((data.rot == 1) || (data.rot == 3)) + delta = zoneBankItem->getSizeX() - 1; + + //item->setPos((zonePos.x - data.posX) * m_cellSize, (abs(int(zonePos.y)) + data.posY - delta) * m_cellSize); + item->setPos((zonePos.x) * m_cellSize, (abs(int(zonePos.y)) - delta) * m_cellSize); // The size graphics item should be equal or proportional m_cellSize item->setScale(float(m_cellSize) / m_zoneBuilder->pixmapDatabase()->textureSize()); + item->setData(ZoneName, QString(data.zoneName.c_str())); + nlinfo("render"); return item; } -QGraphicsItem *LandscapeScene::createEmptyZoneItem(const ZonePosition &zonePos) +QGraphicsItem *LandscapeScene::createItemEmptyZone(const ZonePosition &zonePos) { if (m_zoneBuilder == 0) return 0; - deleteZoneItem(zonePos); - // Get image from pixmap database QPixmap *pixmap = m_zoneBuilder->pixmapDatabase()->pixmap(QString(STRING_UNUSED)); if (pixmap == 0) @@ -118,11 +133,11 @@ QGraphicsItem *LandscapeScene::createEmptyZoneItem(const ZonePosition &zonePos) // The size graphics item should be equal or proportional m_cellSize item->setScale(float(m_cellSize) / m_zoneBuilder->pixmapDatabase()->textureSize()); - + nlinfo("render"); return item; } -void LandscapeScene::deleteZoneItem(const ZonePosition &zonePos) +void LandscapeScene::deleteItemZone(const ZonePosition &zonePos) { QGraphicsItem *item = itemAt(zonePos.x * m_cellSize, abs(zonePos.y) * m_cellSize); if (item != 0) @@ -143,7 +158,7 @@ void LandscapeScene::processZoneRegion(const NLLIGO::CZoneRegion &zoneRegion) if (zoneName == STRING_UNUSED) { ZonePosition zonePos(i, j, -1); - QGraphicsItem *item = createEmptyZoneItem(zonePos); + QGraphicsItem *item = createItemEmptyZone(zonePos); } else if (!zoneName.empty()) { @@ -154,7 +169,7 @@ void LandscapeScene::processZoneRegion(const NLLIGO::CZoneRegion &zoneRegion) data.flip = zoneRegion.getFlip(i, j); data.posX = zoneRegion.getPosX(i, j); data.posY = zoneRegion.getPosY(i, j); - QGraphicsItem *item = createZoneItem(data, zonePos); + QGraphicsItem *item = createItemZone(data, zonePos); } } } @@ -230,13 +245,43 @@ void LandscapeScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) QGraphicsScene::mousePressEvent(mouseEvent); } -void LandscapeScene::checkUnderZone(const LigoData &data, const ZonePosition &zonePos) +void LandscapeScene::mouseMoveEvent(QGraphicsSceneMouseEvent * mouseEvent) { -// NLLIGO::CZoneBankElement *zoneBankItem = m_zoneBuilder->getZoneBank().getElementByZoneName(data.zoneName); -// uint8 sizeX = zoneBankItem->getSizeX(); -// uint8 sizeY = zoneBankItem->getSizeY(); -// std::vector &mask = zoneBankItem->getMask(); - deleteZoneItem(zonePos); + m_mouseX = mouseEvent->scenePos().x(); + m_mouseY = mouseEvent->scenePos().y(); + QGraphicsScene::mouseMoveEvent(mouseEvent); +} + +bool LandscapeScene::checkUnderZone(const int posX, const int posY) +{ + /* QGraphicsItem *item = itemAt((posX * m_cellSize), abs(posY) * m_cellSize); + if (item != 0) + { + QString zoneName = item->data(ZoneName).toString(); + return true; + } + */ return false; +} + +void LandscapeScene::drawForeground(QPainter *painter, const QRectF &rect) +{ + QGraphicsScene::drawForeground(painter, rect); + 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)); + } + } } } /* namespace LandscapeEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h index ea314faac..525971999 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h @@ -43,9 +43,9 @@ public: int cellSize() const; void setZoneBuilder(ZoneBuilder *zoneBuilder); - QGraphicsItem *createZoneItem(const LigoData &data, const ZonePosition &zonePos); - QGraphicsItem *createEmptyZoneItem(const ZonePosition &zonePos); - void deleteZoneItem(const ZonePosition &zonePos); + QGraphicsItem *createItemZone(const LigoData &data, const ZonePosition &zonePos); + QGraphicsItem *createItemEmptyZone(const ZonePosition &zonePos); + void deleteItemZone(const ZonePosition &zonePos); void processZoneRegion(const NLLIGO::CZoneRegion &zoneRegion); void snapshot(const QString &fileName, int sizeSource); @@ -53,11 +53,14 @@ public: protected: virtual void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent); + virtual void mouseMoveEvent(QGraphicsSceneMouseEvent * mouseEvent); + virtual void drawForeground(QPainter *painter, const QRectF &rect); private: - void checkUnderZone(const LigoData &data, const ZonePosition &zonePos); + bool checkUnderZone(const int posX, const int posY); int m_cellSize; + qreal m_mouseX, m_mouseY; ZoneBuilder *m_zoneBuilder; }; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp index 610028762..e32f4ae6d 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp @@ -110,6 +110,8 @@ void LandscapeView::mouseReleaseEvent(QMouseEvent *event) void LandscapeView::drawForeground(QPainter *painter, const QRectF &rect) { + QGraphicsView::drawForeground(painter, rect); + if (!m_visibleGrid) return; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.cpp index 045b342fd..81e4b687c 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.cpp @@ -47,16 +47,33 @@ LigoData::LigoData() sharingCutEdges[3] = 0; } -ZoneRegionEditor::ZoneRegionEditor() +bool LigoData::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]); +} + +ZoneRegionObject::ZoneRegionObject() { m_fileName = ""; } -ZoneRegionEditor::~ZoneRegionEditor() +ZoneRegionObject::~ZoneRegionObject() { } -bool ZoneRegionEditor::load(const std::string &fileName) +bool ZoneRegionObject::load(const std::string &fileName) { bool result = true; try @@ -85,7 +102,7 @@ bool ZoneRegionEditor::load(const std::string &fileName) return result; } -bool ZoneRegionEditor::save() +bool ZoneRegionObject::save() { if (m_fileName.empty()) return false; @@ -123,18 +140,24 @@ bool ZoneRegionEditor::save() return result; } -void ZoneRegionEditor::setFileName(const std::string &fileName) +std::string ZoneRegionObject::fileName() const { - m_fileName = fileName; + return m_fileName; } -void ZoneRegionEditor::ligoData(LigoData &data, const sint32 x, const sint32 y) +void ZoneRegionObject::setFileName(const std::string &fileName) { - nlassert((x >= m_zoneRegion.getMinX()) && - (x <= m_zoneRegion.getMaxX()) && - (y >= m_zoneRegion.getMinY()) && - (y <= m_zoneRegion.getMaxY())); + 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); @@ -150,13 +173,14 @@ void ZoneRegionEditor::ligoData(LigoData &data, const sint32 x, const sint32 y) data.sharingCutEdges[3] = m_zoneRegion.getSharingCutEdges(x, y, 3); } -void ZoneRegionEditor::setLigoData(const LigoData &data, const sint32 x, const sint32 y) +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())); - + /* + 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); @@ -172,14 +196,22 @@ void ZoneRegionEditor::setLigoData(const LigoData &data, const sint32 x, const s m_zoneRegion.setSharingCutEdges(x, y, 3, data.sharingCutEdges[3]); } -NLLIGO::CZoneRegion &ZoneRegionEditor::zoneRegion() +NLLIGO::CZoneRegion &ZoneRegionObject::zoneRegion() { return m_zoneRegion; } -void ZoneRegionEditor::setZoneRegion(const NLLIGO::CZoneRegion &zoneRegion) +void ZoneRegionObject::setZoneRegion(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())); +} + } /* namespace LandscapeEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.h index 50fab0e58..2d4f063aa 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.h @@ -44,29 +44,14 @@ struct LigoData LigoData(); - 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]); - } + bool operator!= (const LigoData& other) const; }; -class ZoneRegionEditor +class ZoneRegionObject { public: - ZoneRegionEditor(); - ~ZoneRegionEditor(); + ZoneRegionObject(); + ~ZoneRegionObject(); // Load landscape data from file bool load(const std::string &fileName); @@ -78,6 +63,8 @@ public: void setLigoData(const LigoData &data, const sint32 x, const sint32 y); + std::string fileName() const; + // Set file name void setFileName(const std::string &fileName); @@ -85,6 +72,8 @@ public: void setZoneRegion(const NLLIGO::CZoneRegion &zoneRegion); + bool checkPos(const sint32 x, const sint32 y); + private: bool m_modified; From 883981fcaac503b1adae8323f197a2cb6462329c Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Thu, 30 Jun 2011 01:51:18 +0300 Subject: [PATCH 10/89] Changed: #1301 Fixed incorrect rendering of rotated elements. --HG-- branch : gsoc2011-worldeditorqt --- .../landscape_editor/landscape_scene.cpp | 115 +++++++++++++----- 1 file changed, 82 insertions(+), 33 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp index 9970032a7..65316d9f7 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp @@ -56,20 +56,15 @@ void LandscapeScene::setZoneBuilder(ZoneBuilder *zoneBuilder) QGraphicsItem *LandscapeScene::createItemZone(const LigoData &data, const ZonePosition &zonePos) { - nlinfo(QString("%1,%2 (%3,%4)-%7 (%5,%6)").arg(zonePos.x).arg(zonePos.y).arg(data.posX).arg(data.posY).arg(data.rot).arg(data.flip).arg(data.zoneName.c_str()).toStdString().c_str()); 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()) || - (data.posX != 0) || (data.posY != 0)) + if ((m_zoneBuilder == 0) || (data.zoneName.empty())) return 0; -// 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) @@ -98,18 +93,69 @@ QGraphicsItem *LandscapeScene::createItemZone(const LigoData &data, const ZonePo // Set position graphics item with offset for large piece NLLIGO::CZoneBankElement *zoneBankItem = m_zoneBuilder->getZoneBank().getElementByZoneName(data.zoneName); - int delta = zoneBankItem->getSizeY() - 1; - if ((data.rot == 1) || (data.rot == 3)) - delta = zoneBankItem->getSizeX() - 1; + sint32 deltaX = 0, deltaY = 0; - //item->setPos((zonePos.x - data.posX) * m_cellSize, (abs(int(zonePos.y)) + data.posY - delta) * m_cellSize); - item->setPos((zonePos.x) * m_cellSize, (abs(int(zonePos.y)) - delta) * m_cellSize); + // Calculate offset for graphics item (for items with size that are larger than 1) + if ((zoneBankItem->getSizeX() > 1) || (zoneBankItem->getSizeY() > 1)) + { + sint32 sizeX = zoneBankItem->getSizeX(), sizeY = zoneBankItem->getSizeY(); + 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 taking into account the offset + 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(ZoneName, QString(data.zoneName.c_str())); - nlinfo("render"); + + // for not full item zone + item->setZValue(0); + return item; } @@ -133,7 +179,10 @@ QGraphicsItem *LandscapeScene::createItemEmptyZone(const ZonePosition &zonePos) // The size graphics item should be equal or proportional m_cellSize item->setScale(float(m_cellSize) / m_zoneBuilder->pixmapDatabase()->textureSize()); - nlinfo("render"); + + // for not full item zone + item->setZValue(1); + return item; } @@ -153,7 +202,7 @@ void LandscapeScene::processZoneRegion(const NLLIGO::CZoneRegion &zoneRegion) { for (sint32 j = zoneRegion.getMinY(); j <= zoneRegion.getMaxY(); ++j) { - nlinfo(QString("%1 %2 %3").arg(i).arg(j).arg(zoneRegion.getName(i, j).c_str()).toStdString().c_str()); + //nlinfo(QString("%1 %2 %3").arg(i).arg(j).arg(zoneRegion.getName(i, j).c_str()).toStdString().c_str()); std::string zoneName = zoneRegion.getName(i, j); if (zoneName == STRING_UNUSED) { @@ -254,34 +303,34 @@ void LandscapeScene::mouseMoveEvent(QGraphicsSceneMouseEvent * mouseEvent) bool LandscapeScene::checkUnderZone(const int posX, const int posY) { - /* QGraphicsItem *item = itemAt((posX * m_cellSize), abs(posY) * m_cellSize); - if (item != 0) - { - QString zoneName = item->data(ZoneName).toString(); - return true; - } - */ return false; + QGraphicsItem *item = itemAt((posX * m_cellSize), abs(posY) * m_cellSize); + if (item != 0) + return true; + return false; } void LandscapeScene::drawForeground(QPainter *painter, const QRectF &rect) { QGraphicsScene::drawForeground(painter, rect); - painter->setPen(QPen(Qt::white, 0.5, Qt::SolidLine)); + /* + // 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)); + 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) + for (int i = left; i < right; ++i) { - 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)); + 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)); + } } - } + */ } } /* namespace LandscapeEditor */ From b1d6db2668b6d1cf05f5196913cef84f1151545a Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Sat, 2 Jul 2011 13:00:28 +0300 Subject: [PATCH 11/89] Fixed: #1301 Fixed incorrect work landscape plugin with other plugins which use opengl (object_viewer plugin). --HG-- branch : gsoc2011-worldeditorqt --- .../landscape_editor_window.cpp | 18 ++++++++++++++---- .../landscape_editor/landscape_editor_window.h | 5 +++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp index facf90264..abfdcbd35 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp @@ -34,14 +34,17 @@ // Qt includes #include #include -#include namespace LandscapeEditor { QString _lastDir; LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent) - : QMainWindow(parent) + : QMainWindow(parent), + m_landscapeScene(0), + m_zoneBuilder(0), + m_undoStack(0), + m_oglWidget(0) { m_ui.setupUi(this); @@ -55,8 +58,9 @@ LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent) m_landscapeScene->setZoneBuilder(m_zoneBuilder); m_ui.graphicsView->setScene(m_landscapeScene); - //m_ui.graphicsView->setViewport(new QGLWidget(QGLFormat(QGL::DoubleBuffer))); - m_ui.graphicsView->setViewport(new QGLWidget(QGLFormat(QGL::DoubleBuffer | QGL::SampleBuffers))); + //m_oglWidget = new QGLWidget(QGLFormat(QGL::DoubleBuffer)); + m_oglWidget = new QGLWidget(QGLFormat(QGL::DoubleBuffer | QGL::SampleBuffers)); + m_ui.graphicsView->setViewport(m_oglWidget); createMenus(); createToolBars(); @@ -150,6 +154,12 @@ void LandscapeEditorWindow::openSnapshotDialog() delete dialog; } +void LandscapeEditorWindow::showEvent(QShowEvent *showEvent) +{ + QMainWindow::showEvent(showEvent); + m_oglWidget->makeCurrent(); +} + void LandscapeEditorWindow::createMenus() { Core::IMenuManager *menuManager = Core::ICore::instance()->menuManager(); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h index ccfcf2778..ff9cfd273 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h @@ -23,6 +23,7 @@ // Qt includes #include +#include namespace LandscapeEditor { @@ -49,6 +50,9 @@ private Q_SLOTS: void openProjectSettings(); void openSnapshotDialog(); +protected: + virtual void showEvent(QShowEvent *showEvent); + private: void createMenus(); void createToolBars(); @@ -58,6 +62,7 @@ private: LandscapeScene *m_landscapeScene; ZoneBuilder *m_zoneBuilder; QUndoStack *m_undoStack; + QGLWidget *m_oglWidget; Ui::LandscapeEditorWindow m_ui; }; /* class LandscapeEditorWindow */ From b2d4da16533cccd04a499d32961f1af9929f7f9f Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Sun, 3 Jul 2011 17:12:31 +0300 Subject: [PATCH 12/89] Fixed: #1301 Fixed build landscape plugin under linux. --HG-- branch : gsoc2011-worldeditorqt --- code/nel/src/ligo/zone_bank.cpp | 13 +++++++------ .../src/plugins/landscape_editor/builder_zone.cpp | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/code/nel/src/ligo/zone_bank.cpp b/code/nel/src/ligo/zone_bank.cpp index 5f03c4bb5..a79b98449 100644 --- a/code/nel/src/ligo/zone_bank.cpp +++ b/code/nel/src/ligo/zone_bank.cpp @@ -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 +#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 &SelectedElements) // *************************************************************************** -} // namespace NLLIGO - -#endif // NL_OS_WINDOWS +} // namespace NLLIGO \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp index 0e00d72be..21ab1118b 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp @@ -78,7 +78,7 @@ bool PixmapDatabase::loadPixmaps(const QString &zonePath, NLLIGO::CZoneBank &zon m_pixmapMap.insert(zonePixmapName, pixmap); } - QPixmap *pixmap = new QPixmap(zonePath + "_UNUSED_.png"); + 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); From 8f223b7950d0a819ed79aa1ab9886353941ad2e9 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Mon, 4 Jul 2011 23:16:45 +0300 Subject: [PATCH 13/89] Changed: #1301 Added random and full cycle modes(for rotation and flip values too) adding zone on landscape. --HG-- branch : gsoc2011-worldeditorqt --- .../landscape_editor/list_zones_widget.cpp | 67 ++++++++++++++++--- .../landscape_editor/list_zones_widget.h | 10 ++- .../landscape_editor/list_zones_widget.ui | 10 ++- 3 files changed, 74 insertions(+), 13 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp index 7ce3f5421..d0bfe058c 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp @@ -38,6 +38,8 @@ namespace LandscapeEditor ListZonesWidget::ListZonesWidget(QWidget *parent) : QWidget(parent), + m_rotCycle(0), + m_flipCycle(0), m_listZonesModel(0), m_zoneBuilder(0) { @@ -101,24 +103,70 @@ void ListZonesWidget::updateUi() m_listZonesModel->rebuildModel(m_zoneBuilder->pixmapDatabase()); } -QString ListZonesWidget::currentZoneName() const +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 + zoneName = m_listSelection[m_zoneNameCycle]; + m_zoneNameCycle++; + m_zoneNameCycle = m_zoneNameCycle % m_listSelection.size(); + } return zoneName; } -int ListZonesWidget::currentRot() const +int ListZonesWidget::currentRot() { - return m_ui.rotComboBox->currentIndex(); + 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() const +int ListZonesWidget::currentFlip() { - return m_ui.flipComboBox->currentIndex(); + 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 @@ -234,11 +282,12 @@ void ListZonesWidget::updateListZones() std::vector currentSelection; zoneBank.getSelection (currentSelection); - QStringList listSelection; + m_listSelection.clear(); + m_zoneNameCycle = 0; for (size_t i = 0; i < currentSelection.size(); ++i) - listSelection << currentSelection[i]->getName().c_str(); + m_listSelection << currentSelection[i]->getName().c_str(); - m_listZonesModel->setListZones(listSelection); + m_listZonesModel->setListZones(m_listSelection); } void ListZonesWidget::disableSignals(bool block) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h index c35e7b0fa..4128f8cc2 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h @@ -45,9 +45,9 @@ public: void updateUi(); void setZoneBuilder(ZoneBuilder *zoneBuilder); - QString currentZoneName() const; - int currentRot() const; - int currentFlip() const; + QString currentZoneName(); + int currentRot(); + int currentFlip(); bool isNotPropogate() const; bool isForce() const; @@ -62,6 +62,10 @@ private Q_SLOTS: 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; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.ui index 4d9f63129..ed9faf74e 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.ui +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.ui @@ -39,7 +39,12 @@ - + + + + Select + + Random @@ -297,6 +302,9 @@ QAbstractItemView::ScrollPerPixel + + 1 + From 500fb8fdfdad82e543341c60727ee776b0cdac5a Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Mon, 4 Jul 2011 23:19:58 +0300 Subject: [PATCH 14/89] Changed: #1301 Class PixmapDatabase was moved to a separate file. --HG-- branch : gsoc2011-worldeditorqt --- .../plugins/landscape_editor/CMakeLists.txt | 1 - .../plugins/landscape_editor/builder_zone.cpp | 86 ------------ .../plugins/landscape_editor/builder_zone.h | 34 +---- .../landscape_editor/pixmap_database.cpp | 132 ++++++++++++++++++ .../landscape_editor/pixmap_database.h | 69 +++++++++ 5 files changed, 202 insertions(+), 120 deletions(-) create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.cpp create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.h diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt index 8c4278c46..2f1d58c66 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt @@ -14,7 +14,6 @@ SET(OVQT_PLUGIN_LANDSCAPE_EDITOR_HDR landscape_editor_plugin.h landscape_scene.h list_zones_model.h list_zones_widget.h - landscape_actions.h landscape_view.h project_settings_dialog.h snapshot_dialog.h diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp index 21ab1118b..843259ddb 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp @@ -32,92 +32,6 @@ namespace LandscapeEditor { -PixmapDatabase::PixmapDatabase() - : m_textureSize(256) -{ -} - -PixmapDatabase::~PixmapDatabase() -{ - reset(); -} - -bool PixmapDatabase::loadPixmaps(const QString &zonePath, NLLIGO::CZoneBank &zoneBank) -{ - QProgressDialog *progressDialog = new QProgressDialog(); - progressDialog->show(); - - std::vector listNames; - zoneBank.getCategoryValues ("zone", listNames); - progressDialog->setRange(0, listNames.size()); - for (uint i = 0; i < listNames.size(); ++i) - { - QApplication::processEvents(); - 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 - } - // All pixmaps must be have same size - 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); - - 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 = 0; - 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; -} - ZoneBuilder::ZoneBuilder(ListZonesWidget *listZonesWidget, LandscapeScene *landscapeScene, QUndoStack *undoStack) : m_currentZoneRegion(-1), m_pixmapDatabase(0), diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h index ecc47976f..da5c2901f 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h @@ -21,6 +21,7 @@ // Project includes #include "builder_zone_region.h" #include "zone_region_editor.h" +#include "pixmap_database.h" // NeL includes #include @@ -67,39 +68,6 @@ struct ZonePosition } }; -/** -@class PixmapDatabase -@brief PixmapDatabase contains the image database -@details -*/ -class PixmapDatabase -{ -public: - PixmapDatabase(); - ~PixmapDatabase(); - - /// Load all images(png) from zonePath, list images gets from zoneBank - bool loadPixmaps(const QString &zonePath, NLLIGO::CZoneBank &zoneBank); - - /// 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; - QMap m_pixmapMap; -}; - - /** @class ZoneBuilder @brief ZoneBuilder contains all the shared data between the tools and the engine. diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.cpp new file mode 100644 index 000000000..f0e2859f6 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.cpp @@ -0,0 +1,132 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +// Project includes +#include "pixmap_database.h" + +// NeL includes +#include +#include + +// STL includes +#include +#include + +// Qt includes +#include +#include +#include +#include + +namespace LandscapeEditor +{ + +PixmapDatabase::PixmapDatabase(int textureSize) + : m_textureSize(textureSize) +{ +} + +PixmapDatabase::~PixmapDatabase() +{ + reset(); +} + +bool PixmapDatabase::loadPixmaps(const QString &zonePath, NLLIGO::CZoneBank &zoneBank, bool displayProgress) +{ + QProgressDialog *progressDialog; + std::vector listNames; + zoneBank.getCategoryValues ("zone", listNames); + if (displayProgress) + { + progressDialog = new QProgressDialog(); + progressDialog->show(); + progressDialog->setRange(0, listNames.size()); + } + + 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 + } + // All pixmaps must be have same size + 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 = 0; + 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 */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.h new file mode 100644 index 000000000..fc90fe180 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.h @@ -0,0 +1,69 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +#ifndef PIXMAP_DATABASE_H +#define PIXMAP_DATABASE_H + +// Project includes +#include "landscape_editor_global.h" + +// NeL includes +#include + +// Qt includes +#include +#include +#include + +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; + QMap m_pixmapMap; +}; + +} /* namespace LandscapeEditor */ + +#endif // PIXMAP_DATABASE_H From e487fac6c75013301379aa3cd0a269150c2d9c56 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Wed, 6 Jul 2011 03:32:02 +0300 Subject: [PATCH 15/89] Changed: #1301 Added flag "modified" in ZoneRegionObject. --HG-- branch : gsoc2011-worldeditorqt --- .../landscape_editor/zone_region_editor.cpp | 14 ++++++++-- .../landscape_editor/zone_region_editor.h | 28 +++++++++++++++---- 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.cpp index 81e4b687c..399d39496 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.cpp @@ -196,12 +196,12 @@ void ZoneRegionObject::setLigoData(const LigoData &data, const sint32 x, const s m_zoneRegion.setSharingCutEdges(x, y, 3, data.sharingCutEdges[3]); } -NLLIGO::CZoneRegion &ZoneRegionObject::zoneRegion() +NLLIGO::CZoneRegion &ZoneRegionObject::ligoZoneRegion() { return m_zoneRegion; } -void ZoneRegionObject::setZoneRegion(const NLLIGO::CZoneRegion &zoneRegion) +void ZoneRegionObject::setLigoZoneRegion(const NLLIGO::CZoneRegion &zoneRegion) { m_zoneRegion = zoneRegion; } @@ -214,4 +214,14 @@ bool ZoneRegionObject::checkPos(const sint32 x, const sint32 y) (y <= m_zoneRegion.getMaxY())); } +bool ZoneRegionObject::isModified() const +{ + return m_modified; +} + +void ZoneRegionObject::setModified(bool modified) +{ + m_modified = modified; +} + } /* namespace LandscapeEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.h index 2d4f063aa..9081d7002 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.h @@ -32,6 +32,7 @@ namespace LandscapeEditor { +// Data struct LigoData { uint8 posX; @@ -47,33 +48,50 @@ struct LigoData bool operator!= (const LigoData& other) const; }; +/** +@class ZoneRegionObject +@brief +@details +*/ class ZoneRegionObject { public: ZoneRegionObject(); ~ZoneRegionObject(); - // Load landscape data from file + /// Load landscape data from file bool load(const std::string &fileName); - // Save landscape data to file + /// 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 + /// Set file name, use for saving data in file void setFileName(const std::string &fileName); - NLLIGO::CZoneRegion &zoneRegion(); + /// Accessor to LIGO CZoneRegion + NLLIGO::CZoneRegion &ligoZoneRegion(); - void setZoneRegion(const NLLIGO::CZoneRegion &zoneRegion); + 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; From bdda6ac1c63b5e0337380c9a1208366f189bd088 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Wed, 6 Jul 2011 03:34:30 +0300 Subject: [PATCH 16/89] Fixed: #1301 Fixed "full cycle" flag with empty list and added comments in list_zones_widget. --HG-- branch : gsoc2011-worldeditorqt --- .../src/plugins/landscape_editor/list_zones_widget.cpp | 9 ++++++--- .../src/plugins/landscape_editor/list_zones_widget.h | 10 +++++++++- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp index d0bfe058c..554b19ca3 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.cpp @@ -122,9 +122,12 @@ QString ListZonesWidget::currentZoneName() else if (m_ui.zoneSelectComboBox->currentIndex() == 2) { // Full cycle - zoneName = m_listSelection[m_zoneNameCycle]; - m_zoneNameCycle++; - m_zoneNameCycle = m_zoneNameCycle % m_listSelection.size(); + if (m_listSelection.size() > 0) + { + zoneName = m_listSelection[m_zoneNameCycle]; + m_zoneNameCycle++; + m_zoneNameCycle = m_zoneNameCycle % m_listSelection.size(); + } } return zoneName; } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h index 4128f8cc2..7298bbe3c 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h @@ -44,14 +44,22 @@ public: ~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; -Q_SIGNALS: private Q_SLOTS: void updateFilters_1(const QString &value); void updateFilters_2(const QString &value); From 5d2c7b0a89d205b1cbd1ed01f6c305991bbe105c Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Wed, 6 Jul 2011 03:43:31 +0300 Subject: [PATCH 17/89] Changed: #1301 Added checking for the overlaps when adding a new landscape. Added blackout inactive landscapes. Operations adding and removing landscapes work correctly. --HG-- branch : gsoc2011-worldeditorqt --- .../plugins/landscape_editor/builder_zone.cpp | 163 +++++++++++++----- .../plugins/landscape_editor/builder_zone.h | 29 +++- .../landscape_editor/builder_zone_region.cpp | 40 ++--- .../landscape_editor/builder_zone_region.h | 2 +- .../landscape_editor/landscape_actions.cpp | 8 +- .../landscape_editor_window.cpp | 19 +- .../landscape_editor/landscape_scene.cpp | 49 ++++-- .../landscape_editor/landscape_scene.h | 15 +- .../landscape_editor/landscape_view.cpp | 2 + 9 files changed, 231 insertions(+), 96 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp index 843259ddb..265e380ca 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp @@ -32,13 +32,14 @@ namespace LandscapeEditor { -ZoneBuilder::ZoneBuilder(ListZonesWidget *listZonesWidget, LandscapeScene *landscapeScene, QUndoStack *undoStack) +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 = ""; } @@ -81,6 +82,9 @@ bool ZoneBuilder::init(const QString &pathName, bool makeAZone) 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); @@ -89,6 +93,9 @@ void ZoneBuilder::actionLigoTile(const LigoData &data, const ZonePosition &zoneP 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)); @@ -96,6 +103,9 @@ void ZoneBuilder::actionLigoMove(uint index, sint32 deltaX, sint32 deltaY) 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)); @@ -103,16 +113,20 @@ void ZoneBuilder::actionLigoResize(uint index, sint32 newMinX, sint32 newMaxX, s void ZoneBuilder::addZone(sint32 posX, sint32 posY) { - if (m_builderZoneRegions.empty()) + // Read-only mode + if ((m_listZonesWidget == 0) || (m_undoStack == 0)) return; + if (m_landscapeItems.empty()) + return; + + // Check zone name std::string zoneName = m_listZonesWidget->currentZoneName().toStdString(); if (zoneName.empty()) return; - std::string error; - BuilderZoneRegion *builderZoneRegion = m_builderZoneRegions.at(m_currentZoneRegion); - builderZoneRegion->init(this, error); + BuilderZoneRegion *builderZoneRegion = m_landscapeItems.at(m_currentZoneRegion).builderZoneRegion; + builderZoneRegion->init(this); uint8 rot = uint8(m_listZonesWidget->currentRot()); uint8 flip = uint8(m_listZonesWidget->currentFlip()); @@ -122,8 +136,6 @@ void ZoneBuilder::addZone(sint32 posX, sint32 posY) m_titleAction = QString("Add zone %1,%2").arg(posX).arg(posY); m_createdAction = false; m_zonePositionList.clear(); - - nlinfo("---------"); if (m_listZonesWidget->isForce()) { builderZoneRegion->addForce(posX, posY, rot, flip, zoneBankElement); @@ -140,45 +152,95 @@ void ZoneBuilder::addZone(sint32 posX, sint32 posY) void ZoneBuilder::addTransition(const sint32 posX, const sint32 posY) { + if ((m_listZonesWidget == 0) || (m_undoStack == 0)) + return; } void ZoneBuilder::delZone(const sint32 posX, const sint32 posY) { - if (m_builderZoneRegions.empty()) + if ((m_listZonesWidget == 0) || (m_undoStack == 0)) + return; + + if (m_landscapeItems.empty()) return; m_titleAction = QString("Del zone %1,%2").arg(posX).arg(posY); m_createdAction = false; - BuilderZoneRegion *builderZoneRegion = m_builderZoneRegions.at(m_currentZoneRegion); - std::string error; - nlinfo("---------"); - builderZoneRegion->init(this, error); + BuilderZoneRegion *builderZoneRegion = m_landscapeItems.at(m_currentZoneRegion).builderZoneRegion; + + builderZoneRegion->init(this); builderZoneRegion->del(posX, posY); checkEndMacro(); } int ZoneBuilder::createZoneRegion() { - ZoneRegionObject *newZoneRegion = new ZoneRegionObject(); - m_zoneRegions.push_back(newZoneRegion); + int newId = m_landscapeItems.size(); + LandscapeItem landItem; + landItem.zoneRegionObject = new ZoneRegionObject(); + landItem.builderZoneRegion = new BuilderZoneRegion(newId); + landItem.builderZoneRegion->init(this); + landItem.rectItem = 0; + + newZone(); + m_landscapeItems.push_back(landItem); if (m_currentZoneRegion == -1) - m_currentZoneRegion = m_zoneRegions.indexOf(newZoneRegion); + setCurrentZoneRegion(newId); + + return newId; +} + +int ZoneBuilder::createZoneRegion(const QString &fileName) +{ + int newId = m_landscapeItems.size(); + 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(newId); + landItem.builderZoneRegion->init(this); newZone(); - return m_zoneRegions.indexOf(newZoneRegion); + m_landscapeItems.push_back(landItem); + + m_landscapeScene->addZoneRegion(landItem.zoneRegionObject->ligoZoneRegion()); + m_landscapeItems.at(newId).rectItem = m_landscapeScene->createLayerBlackout(landItem.zoneRegionObject->ligoZoneRegion()); + + if (m_currentZoneRegion == -1) + setCurrentZoneRegion(newId); + + return newId; } void ZoneBuilder::deleteZoneRegion(int id) { - if ((0 <= id) && (id < m_zoneRegions.size())) - delete m_zoneRegions.takeAt(id); + if ((0 <= id) && (id < int(m_landscapeItems.size()))) + { + m_landscapeScene->delZoneRegion(m_landscapeItems.at(id).zoneRegionObject->ligoZoneRegion()); + delete m_landscapeItems.at(id).zoneRegionObject; + delete m_landscapeItems.at(id).builderZoneRegion; + delete m_landscapeItems.at(id).rectItem; + m_landscapeItems.erase(m_landscapeItems.begin() + id); + calcMask(); + } } void ZoneBuilder::setCurrentZoneRegion(int id) { - if ((0 <= id) && (id < m_zoneRegions.size())) + if ((0 <= id) && (id < int(m_landscapeItems.size()))) + { + if (currentIdZoneRegion() != -1) + m_landscapeItems.at(m_currentZoneRegion).rectItem = m_landscapeScene->createLayerBlackout(currentZoneRegion()->ligoZoneRegion()); m_currentZoneRegion = id; + delete m_landscapeItems.at(id).rectItem; + m_landscapeItems.at(id).rectItem = 0; + } } int ZoneBuilder::currentIdZoneRegion() const @@ -188,27 +250,27 @@ int ZoneBuilder::currentIdZoneRegion() const ZoneRegionObject *ZoneBuilder::currentZoneRegion() const { - return m_zoneRegions.at(m_currentZoneRegion); + return m_landscapeItems.at(m_currentZoneRegion).zoneRegionObject; } int ZoneBuilder::countZoneRegion() const { - return m_zoneRegions.size(); + return m_landscapeItems.size(); } ZoneRegionObject *ZoneBuilder::zoneRegion(int id) const { - return m_zoneRegions.at(id); + return m_landscapeItems.at(id).zoneRegionObject; } void ZoneBuilder::ligoData(LigoData &data, const ZonePosition &zonePos) { - m_zoneRegions.at(zonePos.region)->ligoData(data, zonePos.x, zonePos.y); + m_landscapeItems.at(zonePos.region).zoneRegionObject->ligoData(data, zonePos.x, zonePos.y); } void ZoneBuilder::setLigoData(LigoData &data, const ZonePosition &zonePos) { - m_zoneRegions.at(zonePos.region)->setLigoData(data, zonePos.x, zonePos.y); + m_landscapeItems.at(zonePos.region).zoneRegionObject->setLigoData(data, zonePos.x, zonePos.y); } bool ZoneBuilder::initZoneBank (const QString &pathName) @@ -243,16 +305,13 @@ QString ZoneBuilder::dataPath() const void ZoneBuilder::newZone() { - BuilderZoneRegion *builderZoneRegion = new BuilderZoneRegion(m_builderZoneRegions.size()); - m_builderZoneRegions.push_back(builderZoneRegion); - // Select starting point for the moment 0,0 sint32 x = 0, y = 0; // If there are some zone already present increase x until free - for (int i = 0; i < m_zoneRegions.size(); ++i) + for (size_t i = 0; i < m_landscapeItems.size(); ++i) { - const NLLIGO::CZoneRegion &zoneRegion = m_zoneRegions.at(i)->zoneRegion(); + const NLLIGO::CZoneRegion &zoneRegion = m_landscapeItems.at(i).zoneRegionObject->ligoZoneRegion(); const std::string &zoneName = zoneRegion.getName (x, y); if ((zoneName != STRING_OUT_OF_BOUND) && (zoneName != STRING_UNUSED)) { @@ -278,18 +337,17 @@ bool ZoneBuilder::getZoneMask(sint32 x, sint32 y) void ZoneBuilder::calcMask() { - sint32 i; sint32 x, y; m_minY = m_minX = 1000000; m_maxY = m_maxX = -1000000; - if (m_builderZoneRegions.size() == 0) + if (m_landscapeItems.size() == 0) return; - for (i = 0; i < (sint32)m_builderZoneRegions.size(); ++i) + for (size_t i = 0; i < m_landscapeItems.size(); ++i) { - const NLLIGO::CZoneRegion ®ion = zoneRegion(i)->zoneRegion(); + const NLLIGO::CZoneRegion ®ion = m_landscapeItems.at(i).zoneRegionObject->ligoZoneRegion(); if (m_minX > region.getMinX()) m_minX = region.getMinX(); @@ -308,10 +366,10 @@ void ZoneBuilder::calcMask() { m_zoneMask[x - m_minX + (y - m_minY) * stride] = true; - for (i = 0; i < (sint32)m_builderZoneRegions.size(); ++i) - if (i != m_currentZoneRegion) + for (size_t i = 0; i < m_landscapeItems.size(); ++i) + if (int(i) != m_currentZoneRegion) { - const NLLIGO::CZoneRegion ®ion = zoneRegion(i)->zoneRegion(); + const NLLIGO::CZoneRegion ®ion = zoneRegion(i)->ligoZoneRegion(); const std::string &rSZone = region.getName (x, y); if ((rSZone != STRING_OUT_OF_BOUND) && (rSZone != STRING_UNUSED)) @@ -322,25 +380,24 @@ void ZoneBuilder::calcMask() } } -bool ZoneBuilder::getZoneAmongRegions (ZonePosition &zonePos, BuilderZoneRegion *builderZoneRegionFrom, sint32 x, sint32 y) +bool ZoneBuilder::getZoneAmongRegions(ZonePosition &zonePos, BuilderZoneRegion *builderZoneRegionFrom, sint32 x, sint32 y) { - Q_FOREACH(ZoneRegionObject *zoneRegion, m_zoneRegions) + for (size_t i = 0; i < m_landscapeItems.size(); ++i) { - const NLLIGO::CZoneRegion ®ion = zoneRegion->zoneRegion(); + const NLLIGO::CZoneRegion ®ion = m_landscapeItems.at(i).zoneRegionObject->ligoZoneRegion(); if ((x < region.getMinX()) || (x > region.getMaxX()) || (y < region.getMinY()) || (y > region.getMaxY())) continue; if (region.getName(x, y) != STRING_UNUSED) { - int index = m_zoneRegions.indexOf(zoneRegion); - builderZoneRegionFrom = m_builderZoneRegions.at(index); - zonePos = ZonePosition(x, y, index); + builderZoneRegionFrom = m_landscapeItems.at(i).builderZoneRegion; + zonePos = ZonePosition(x, y, i); return true; } } // The zone is not present in other region so it is an empty or oob zone of the current region - const NLLIGO::CZoneRegion ®ion = zoneRegion(builderZoneRegionFrom->getRegionId())->zoneRegion(); + const NLLIGO::CZoneRegion ®ion = zoneRegion(builderZoneRegionFrom->getRegionId())->ligoZoneRegion(); if ((x < region.getMinX()) || (x > region.getMaxX()) || (y < region.getMinY()) || (y > region.getMaxY())) return false; // Out Of Bound @@ -372,4 +429,24 @@ void ZoneBuilder::checkEndMacro() } } +bool ZoneBuilder::checkOverlaps(const NLLIGO::CZoneRegion &newZoneRegion) +{ + for (size_t j = 0; j < m_landscapeItems.size(); ++j) + { + const NLLIGO::CZoneRegion &zoneRegion = m_landscapeItems.at(j).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 */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h index da5c2901f..17d5a6f7e 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h @@ -38,6 +38,7 @@ #include #include #include +#include namespace LandscapeEditor { @@ -77,7 +78,7 @@ PixmapDatabase contains the graphics for the zones class ZoneBuilder { public: - ZoneBuilder(ListZonesWidget *listZonesWidget, LandscapeScene *landscapeScene, QUndoStack *undoStack); + ZoneBuilder(LandscapeScene *landscapeScene, ListZonesWidget *listZonesWidget = 0, QUndoStack *undoStack = 0); ~ZoneBuilder(); /// Init zoneBank and init zone pixmap database @@ -88,18 +89,24 @@ public: bool getZoneMask (sint32 x, sint32 y); bool getZoneAmongRegions(ZonePosition &zonePos, BuilderZoneRegion *builderZoneRegionFrom, sint32 x, sint32 y); - // Ligo Actions + /// 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 + /// Zone Bricks + /// @{ void addZone(sint32 posX, sint32 posY); void addTransition(const sint32 posX, const sint32 posY); void delZone(const sint32 posX, const sint32 posY); + /// @} - // Zone Region + /// Zone Region + /// @{ int createZoneRegion(); + int createZoneRegion(const QString &fileName); void deleteZoneRegion(int id); void setCurrentZoneRegion(int id); int currentIdZoneRegion() const; @@ -108,6 +115,7 @@ public: ZoneRegionObject *zoneRegion(int id) const; void ligoData(LigoData &data, const ZonePosition &zonePos); void setLigoData(LigoData &data, const ZonePosition &zonePos); + /// @} // Accessors NLLIGO::CZoneBank &getZoneBank() @@ -127,15 +135,22 @@ private: 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 m_zoneMask; QString m_lastPathName; - QList m_zoneRegions; int m_currentZoneRegion; - - std::vector m_builderZoneRegions; + std::vector m_landscapeItems; bool m_createdAction; QString m_titleAction; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.cpp index 2a4fc204a..b294ce97b 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.cpp @@ -35,7 +35,7 @@ BuilderZoneRegion::BuilderZoneRegion(uint regionId) { } -bool BuilderZoneRegion::init(ZoneBuilder *zoneBuilder, std::string &error) +bool BuilderZoneRegion::init(ZoneBuilder *zoneBuilder) { if (m_firstInit) return true; @@ -264,7 +264,7 @@ void BuilderZoneRegion::add(sint32 x, sint32 y, uint8 rot, uint8 flip, NLLIGO::C void BuilderZoneRegion::invertCutEdge(sint32 x, sint32 y, uint8 cePos) { - const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion(); + const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->ligoZoneRegion(); if ((x < zoneRegion.getMinX ()) || (x > zoneRegion.getMaxX ()) || (y < zoneRegion.getMinY ()) || (y > zoneRegion.getMaxY ())) return; @@ -371,7 +371,7 @@ void BuilderZoneRegion::invertCutEdge(sint32 x, sint32 y, uint8 cePos) void BuilderZoneRegion::cycleTransition(sint32 x, sint32 y) { - const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion(); + const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->ligoZoneRegion(); if ((x < zoneRegion.getMinX ()) || (x > zoneRegion.getMaxX ()) || (y < zoneRegion.getMinY ()) || (y > zoneRegion.getMaxY ())) return; @@ -391,7 +391,7 @@ void BuilderZoneRegion::cycleTransition(sint32 x, sint32 y) bool BuilderZoneRegion::addNotPropagate (sint32 x, sint32 y, uint8 rot, uint8 flip, NLLIGO::CZoneBankElement *zoneBankElement) { - const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion(); + const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->ligoZoneRegion(); sint32 sizeX = zoneBankElement->getSizeX(), sizeY = zoneBankElement->getSizeY(); sint32 i, j; NLLIGO::SPiece sMask, sPosX, sPosY; @@ -472,7 +472,7 @@ bool BuilderZoneRegion::addNotPropagate (sint32 x, sint32 y, uint8 rot, uint8 fl void BuilderZoneRegion::addForce (sint32 x, sint32 y, uint8 rot, uint8 flip, NLLIGO::CZoneBankElement *zoneBankElement) { - const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion(); + const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->ligoZoneRegion(); sint32 sizeX = zoneBankElement->getSizeX(), sizeY = zoneBankElement->getSizeY(); sint32 i, j; NLLIGO::SPiece sMask, sPosX, sPosY; @@ -636,7 +636,7 @@ uint8 TransToEdge[72][4] = void BuilderZoneRegion::addTransition (sint32 x, sint32 y, uint8 rot, uint8 flip, NLLIGO::CZoneBankElement *zoneBankElement) { - const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion(); + const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->ligoZoneRegion(); uint32 i; // Check that we write in an already defined place if ((x < zoneRegion.getMinX ()) || (x > zoneRegion.getMaxX ()) || @@ -806,7 +806,7 @@ void BuilderZoneRegion::addTransition (sint32 x, sint32 y, uint8 rot, uint8 flip void BuilderZoneRegion::addToUpdateAndCreate(BuilderZoneRegion* builderZoneRegion, sint32 sharePos, sint32 x, sint32 y, const std::string &newMat, void *pInt1, void *pInt2) { - const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion(); + const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->ligoZoneRegion(); ToUpdate *ptCreate = reinterpret_cast(pInt1); ToUpdate *ptUpdate = reinterpret_cast(pInt2); sint32 stride = (1 + zoneRegion.getMaxX() - zoneRegion.getMinX()); @@ -831,7 +831,7 @@ void BuilderZoneRegion::addToUpdateAndCreate(BuilderZoneRegion* builderZoneRegio void BuilderZoneRegion::putTransitions (sint32 inX, sint32 inY, const NLLIGO::SPiece &mask, const std::string &matName, void *pInternal) { - const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion(); + const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->ligoZoneRegion(); ToUpdate tCreate; // Transition to create ToUpdate *ptUpdate = reinterpret_cast(pInternal); // Transition to update @@ -984,7 +984,7 @@ void BuilderZoneRegion::putTransitions (sint32 inX, sint32 inY, const NLLIGO::SP // For all transition to update choose the cut edge for (m = 0; m < (sint32)tCreate.size(); ++m) { - const NLLIGO::CZoneRegion &zoneRegion2 = m_zoneBuilder->zoneRegion(tCreate.getBuilderZoneRegion(m)->getRegionId())->zoneRegion(); + const NLLIGO::CZoneRegion &zoneRegion2 = m_zoneBuilder->zoneRegion(tCreate.getBuilderZoneRegion(m)->getRegionId())->ligoZoneRegion(); x = tCreate.getX(m); y = tCreate.getY(m); @@ -1145,7 +1145,7 @@ void BuilderZoneRegion::putTransitions (sint32 inX, sint32 inY, const NLLIGO::SP // Finally update all transition for (m = 0; m < (sint32)tCreate.size(); ++m) { - const NLLIGO::CZoneRegion &zoneRegion2 = m_zoneBuilder->zoneRegion(tCreate.getBuilderZoneRegion(m)->getRegionId())->zoneRegion(); + const NLLIGO::CZoneRegion &zoneRegion2 = m_zoneBuilder->zoneRegion(tCreate.getBuilderZoneRegion(m)->getRegionId())->ligoZoneRegion(); x = tCreate.getX(m); y = tCreate.getY(m); @@ -1155,7 +1155,7 @@ void BuilderZoneRegion::putTransitions (sint32 inX, sint32 inY, const NLLIGO::SP } for (m = 0; m < (sint32)ptUpdate->size(); ++m) { - const NLLIGO::CZoneRegion &zoneRegion2 = m_zoneBuilder->zoneRegion(tCreate.getBuilderZoneRegion(m)->getRegionId())->zoneRegion(); + const NLLIGO::CZoneRegion &zoneRegion2 = m_zoneBuilder->zoneRegion(tCreate.getBuilderZoneRegion(m)->getRegionId())->ligoZoneRegion(); x = ptUpdate->getX(m); y = ptUpdate->getY(m); if ((x >= zoneRegion2.getMinX()) && (x <= zoneRegion2.getMaxX()) && @@ -1166,7 +1166,7 @@ void BuilderZoneRegion::putTransitions (sint32 inX, sint32 inY, const NLLIGO::SP // Cross material for (m = 0; m < (sint32)tCreate.size(); ++m) { - const NLLIGO::CZoneRegion &zoneRegion2 = m_zoneBuilder->zoneRegion(tCreate.getBuilderZoneRegion(m)->getRegionId())->zoneRegion(); + const NLLIGO::CZoneRegion &zoneRegion2 = m_zoneBuilder->zoneRegion(tCreate.getBuilderZoneRegion(m)->getRegionId())->ligoZoneRegion(); x = tCreate.getX(m); y = tCreate.getY(m); @@ -1363,7 +1363,7 @@ STrans TranConvTable[128] = void BuilderZoneRegion::updateTrans (sint32 x, sint32 y, NLLIGO::CZoneBankElement *zoneBankElement) { - const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion(); + const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->ligoZoneRegion(); if ((x < zoneRegion.getMinX()) || (x > zoneRegion.getMaxX()) || (y < zoneRegion.getMinY()) || (y > zoneRegion.getMaxY())) return; @@ -1564,7 +1564,7 @@ void BuilderZoneRegion::updateTrans (sint32 x, sint32 y, NLLIGO::CZoneBankElemen std::string BuilderZoneRegion::getNextMatInTree (const std::string &matA, const std::string &matB) { - const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion(); + const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->ligoZoneRegion(); uint32 i, posA = 10000, posB = 10000; if (matA == matB) @@ -1600,7 +1600,7 @@ struct SNode void BuilderZoneRegion::tryPath(uint32 posA, uint32 posB, std::vector &path) { - const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion(); + const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->ligoZoneRegion(); // Build the adjascence matrix std::vector matAdj; @@ -1662,7 +1662,7 @@ void BuilderZoneRegion::tryPath(uint32 posA, uint32 posB, std::vector &p void BuilderZoneRegion::del(sint32 x, sint32 y, bool transition, void *pInternal) { - const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion(); + const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->ligoZoneRegion(); if (!m_zoneBuilder->getZoneMask(x, y)) return; @@ -1783,7 +1783,7 @@ void BuilderZoneRegion::move (sint32 x, sint32 y) uint32 BuilderZoneRegion::countZones () { - const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion(); + const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->ligoZoneRegion(); sint32 x, y; uint32 counter = 0; @@ -1799,7 +1799,7 @@ uint32 BuilderZoneRegion::countZones () void BuilderZoneRegion::set(sint32 x, sint32 y, sint32 posX, sint32 posY, const std::string &zoneName, bool transition) { - const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion(); + const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->ligoZoneRegion(); // Do we need to resize ? if ((x < zoneRegion.getMinX()) || (x > zoneRegion.getMaxX()) || @@ -1988,7 +1988,7 @@ void BuilderZoneRegion::setFlip(sint32 x, sint32 y, uint8 flip) void BuilderZoneRegion::reduceMin () { - const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion(); + const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->ligoZoneRegion(); sint32 i, j; sint32 newMinX = zoneRegion.getMinX(), newMinY = zoneRegion.getMinY (); @@ -2099,7 +2099,7 @@ uint BuilderZoneRegion::getRegionId() const void BuilderZoneRegion::resize (sint32 newMinX, sint32 newMaxX, sint32 newMinY, sint32 newMaxY) { - const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->zoneRegion(); + const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->ligoZoneRegion(); if ((zoneRegion.getMinX ()!= newMinX) || (zoneRegion.getMaxX ()!= newMaxX) || (zoneRegion.getMinY ()!= newMinY) || diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.h index 7322e47b6..63656d643 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.h @@ -43,7 +43,7 @@ public: BuilderZoneRegion(uint regionId); // New interface - bool init(ZoneBuilder *zoneBuilder, std::string &error); + 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); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp index 8aea79933..4fcf36efe 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp @@ -114,7 +114,6 @@ void UndoScanRegionCommand::undo() { for (int i = 0; i < m_zonePositionList.size(); ++i) m_scene->deleteItemZone(m_zonePositionList.at(i)); - nlinfo("------"); for (int i = 0; i < m_zonePositionList.size(); ++i) { LigoData data; @@ -152,7 +151,6 @@ void RedoScanRegionCommand::redo() { for (int i = 0; i < m_zonePositionList.size(); ++i) m_scene->deleteItemZone(m_zonePositionList.at(i)); - nlinfo("------"); for (int i = 0; i < m_zonePositionList.size(); ++i) { LigoData data; @@ -174,7 +172,7 @@ LigoResizeCommand::LigoResizeCommand(int index, sint32 newMinX, sint32 newMaxX, m_newMaxY = newMaxY; // Backup old region zone - m_oldZoneRegion = m_zoneBuilder->zoneRegion(m_index)->zoneRegion(); + m_oldZoneRegion = m_zoneBuilder->zoneRegion(m_index)->ligoZoneRegion(); } LigoResizeCommand::~LigoResizeCommand() @@ -184,13 +182,13 @@ LigoResizeCommand::~LigoResizeCommand() void LigoResizeCommand::undo () { // Restore old region zone - m_zoneBuilder->zoneRegion(m_index)->setZoneRegion(m_oldZoneRegion); + m_zoneBuilder->zoneRegion(m_index)->setLigoZoneRegion(m_oldZoneRegion); } void LigoResizeCommand::redo () { // Get the zone region - NLLIGO::CZoneRegion ®ion = m_zoneBuilder->zoneRegion(m_index)->zoneRegion(); + NLLIGO::CZoneRegion ®ion = m_zoneBuilder->zoneRegion(m_index)->ligoZoneRegion(); sint32 i, j; std::vector newZones; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp index abfdcbd35..f2e2773be 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp @@ -34,6 +34,7 @@ // Qt includes #include #include +#include namespace LandscapeEditor { @@ -51,7 +52,7 @@ LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent) m_undoStack = new QUndoStack(this); m_landscapeScene = new LandscapeScene(this); - m_zoneBuilder = new ZoneBuilder(m_ui.zoneListWidget, m_landscapeScene, m_undoStack); + m_zoneBuilder = new ZoneBuilder(m_landscapeScene, m_ui.zoneListWidget, m_undoStack); m_zoneBuilder->init("e:/-nel-/install/continents/newbieland", true); m_ui.zoneListWidget->setZoneBuilder(m_zoneBuilder); m_ui.zoneListWidget->updateUi(); @@ -96,12 +97,15 @@ void LandscapeEditorWindow::open() _lastDir = QFileInfo(list.front()).absolutePath(); Q_FOREACH(QString fileName, fileNames) { - int id = m_zoneBuilder->createZoneRegion(); + int id = m_zoneBuilder->createZoneRegion(fileName); + if (id == -1) + { + QMessageBox::critical(this, "Landscape Editor", "Cannot add this zone because it overlaps existing ones"); + continue; + } ZoneRegionObject *zoneRegion = m_zoneBuilder->zoneRegion(id); - zoneRegion->load(fileName.toStdString()); - m_landscapeScene->processZoneRegion(zoneRegion->zoneRegion()); - m_ui.graphicsView->centerOn(zoneRegion->zoneRegion().getMinX() * m_landscapeScene->cellSize(), - abs(zoneRegion->zoneRegion().getMinY()) * m_landscapeScene->cellSize()); + m_ui.graphicsView->centerOn(zoneRegion->ligoZoneRegion().getMinX() * m_landscapeScene->cellSize(), + abs(zoneRegion->ligoZoneRegion().getMinY()) * m_landscapeScene->cellSize()); m_zoneBuilder->setCurrentZoneRegion(id); } @@ -157,7 +161,8 @@ void LandscapeEditorWindow::openSnapshotDialog() void LandscapeEditorWindow::showEvent(QShowEvent *showEvent) { QMainWindow::showEvent(showEvent); - m_oglWidget->makeCurrent(); + if (m_oglWidget != 0) + m_oglWidget->makeCurrent(); } void LandscapeEditorWindow::createMenus() diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp index 65316d9f7..82606f74a 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp @@ -17,6 +17,7 @@ // Project includes #include "landscape_scene.h" +#include "pixmap_database.h" // NeL includes #include @@ -29,7 +30,10 @@ namespace LandscapeEditor { -static const int ZoneName = 0; +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; LandscapeScene::LandscapeScene(QObject *parent) : QGraphicsScene(parent), @@ -78,19 +82,18 @@ QGraphicsItem *LandscapeScene::createItemZone(const LigoData &data, const ZonePo if (data.flip == 0) { - item = new QGraphicsPixmapItem(pixmap->transformed(matrix, Qt::SmoothTransformation), 0, this); + item = addPixmap(pixmap->transformed(matrix, Qt::SmoothTransformation)); } else { // mirror image QImage mirrorImage = pixmap->toImage(); QPixmap mirrorPixmap = QPixmap::fromImage(mirrorImage.mirrored(true, false)); - item = new QGraphicsPixmapItem(mirrorPixmap.transformed(matrix, Qt::SmoothTransformation), 0, this); + item = addPixmap(mirrorPixmap.transformed(matrix, Qt::SmoothTransformation)); } // Enable bilinear filtering item->setTransformationMode(Qt::SmoothTransformation); - // Set position graphics item with offset for large piece NLLIGO::CZoneBankElement *zoneBankItem = m_zoneBuilder->getZoneBank().getElementByZoneName(data.zoneName); sint32 deltaX = 0, deltaY = 0; @@ -145,16 +148,16 @@ QGraphicsItem *LandscapeScene::createItemZone(const LigoData &data, const ZonePo } } - // set position graphics item with taking into account the offset + // 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(ZoneName, QString(data.zoneName.c_str())); + //item->setData(ZONE_NAME, QString(data.zoneName.c_str())); // for not full item zone - item->setZValue(0); + item->setZValue(LAYER_ZONES); return item; } @@ -169,7 +172,7 @@ QGraphicsItem *LandscapeScene::createItemEmptyZone(const ZonePosition &zonePos) if (pixmap == 0) return 0; - QGraphicsPixmapItem *item = new QGraphicsPixmapItem(*pixmap, 0, this); + QGraphicsPixmapItem *item = addPixmap(*pixmap); // Enable bilinear filtering item->setTransformationMode(Qt::SmoothTransformation); @@ -181,11 +184,23 @@ QGraphicsItem *LandscapeScene::createItemEmptyZone(const ZonePosition &zonePos) item->setScale(float(m_cellSize) / m_zoneBuilder->pixmapDatabase()->textureSize()); // for not full item zone - item->setZValue(1); + item->setZValue(LAYER_EMPTY_ZONES); 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); + return rectItem; +} + void LandscapeScene::deleteItemZone(const ZonePosition &zonePos) { QGraphicsItem *item = itemAt(zonePos.x * m_cellSize, abs(zonePos.y) * m_cellSize); @@ -196,12 +211,13 @@ void LandscapeScene::deleteItemZone(const ZonePosition &zonePos) } } -void LandscapeScene::processZoneRegion(const NLLIGO::CZoneRegion &zoneRegion) +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) { + //nlinfo(QString("%1 %2 %3").arg(i).arg(j).arg(zoneRegion.getName(i, j).c_str()).toStdString().c_str()); std::string zoneName = zoneRegion.getName(i, j); if (zoneName == STRING_UNUSED) @@ -224,6 +240,17 @@ void LandscapeScene::processZoneRegion(const NLLIGO::CZoneRegion &zoneRegion) } } +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 sizeSource) { /* if (m_zoneRegion == 0) @@ -305,7 +332,9 @@ bool LandscapeScene::checkUnderZone(const int posX, const int posY) { QGraphicsItem *item = itemAt((posX * m_cellSize), abs(posY) * m_cellSize); if (item != 0) + { return true; + } return false; } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h index 525971999..7e60febaf 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h @@ -21,6 +21,7 @@ // Project includes #include "zone_region_editor.h" #include "builder_zone.h" +#include "landscape_editor_global.h" // NeL includes #include @@ -32,7 +33,12 @@ namespace LandscapeEditor { -class LandscapeScene : public QGraphicsScene +/** +@class LandscapeScene +@brief +@details +*/ +class LANDSCAPE_EDITOR_EXPORT LandscapeScene : public QGraphicsScene { Q_OBJECT @@ -45,15 +51,18 @@ public: 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 processZoneRegion(const NLLIGO::CZoneRegion &zoneRegion); + + void addZoneRegion(const NLLIGO::CZoneRegion &zoneRegion); + void delZoneRegion(const NLLIGO::CZoneRegion &zoneRegion); void snapshot(const QString &fileName, int sizeSource); void snapshot(const QString &fileName, int width, int height); protected: virtual void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent); - virtual void mouseMoveEvent(QGraphicsSceneMouseEvent * mouseEvent); + virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent); virtual void drawForeground(QPainter *painter, const QRectF &rect); private: diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp index e32f4ae6d..84bc4b47d 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp @@ -41,6 +41,7 @@ LandscapeView::LandscapeView(QWidget *parent) setBackgroundBrush(QBrush(Qt::lightGray)); //setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate); //setRenderHints(QPainter::Antialiasing); + //setCacheMode(QGraphicsView::CacheBackground); m_cellSize = 160; m_numSteps = 0; m_maxSteps = 20; @@ -83,6 +84,7 @@ void LandscapeView::wheelEvent(QWheelEvent *event) --m_numSteps; } scale(factor, factor); + QGraphicsView::wheelEvent(event); } void LandscapeView::mousePressEvent(QMouseEvent *event) From 808d0f1b8e53f7fa3044597b5d32bab4a81e8771 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Wed, 6 Jul 2011 04:38:38 +0300 Subject: [PATCH 18/89] Changed: #1301 Completed snapshot dialog. --HG-- branch : gsoc2011-worldeditorqt --- .../landscape_editor_window.cpp | 28 +++++++++- .../landscape_editor/landscape_scene.cpp | 54 +++++-------------- .../landscape_editor/landscape_scene.h | 3 +- .../landscape_editor/shapshot_dialog.ui | 40 +++++++++----- .../landscape_editor/snapshot_dialog.cpp | 26 +++++++++ .../landscape_editor/snapshot_dialog.h | 6 +++ 6 files changed, 100 insertions(+), 57 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp index f2e2773be..5f5fad552 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp @@ -152,7 +152,33 @@ void LandscapeEditorWindow::openSnapshotDialog() tr("Image file (*.png)")); setCursor(Qt::WaitCursor); - m_landscapeScene->snapshot(fileName, 128); + + 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; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp index 82606f74a..81a94fb1f 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp @@ -218,7 +218,6 @@ void LandscapeScene::addZoneRegion(const NLLIGO::CZoneRegion &zoneRegion) for (sint32 j = zoneRegion.getMinY(); j <= zoneRegion.getMaxY(); ++j) { - //nlinfo(QString("%1 %2 %3").arg(i).arg(j).arg(zoneRegion.getName(i, j).c_str()).toStdString().c_str()); std::string zoneName = zoneRegion.getName(i, j); if (zoneName == STRING_UNUSED) { @@ -251,53 +250,26 @@ void LandscapeScene::delZoneRegion(const NLLIGO::CZoneRegion &zoneRegion) } } -void LandscapeScene::snapshot(const QString &fileName, int sizeSource) -{ - /* if (m_zoneRegion == 0) - return; - - sint32 regionMinX = m_zoneRegion->getMinX(); - sint32 regionMaxX = m_zoneRegion->getMaxX(); - sint32 regionMinY = m_zoneRegion->getMinY(); - sint32 regionMaxY = m_zoneRegion->getMaxY(); - - int regionWidth = (regionMaxX - regionMinX + 1); - int regionHeight = (regionMaxY - regionMinY + 1); - - snapshot(fileName, regionWidth * sizeSource, regionHeight * sizeSource); - */ -} - -void LandscapeScene::snapshot(const QString &fileName, int width, int height) +void LandscapeScene::snapshot(const QString &fileName, int width, int height, const QRectF &landRect) { if (m_zoneBuilder == 0) return; - /* if (m_zoneRegion == 0) - return; - - sint32 regionMinX = m_zoneRegion->getMinX(); - sint32 regionMaxX = m_zoneRegion->getMaxX(); - sint32 regionMinY = m_zoneRegion->getMinY(); - sint32 regionMaxY = m_zoneRegion->getMaxY(); - - int regionWidth = (regionMaxX - regionMinX + 1); - int regionHeight = (regionMaxY - regionMinY + 1); + // Create image + QImage image(landRect.width(), landRect.height(), QImage::Format_RGB888); + QPainter painter(&image); + painter.setRenderHint(QPainter::Antialiasing, true); - QImage image(width, 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()); - // add white background - painter.setBrush(QBrush(Qt::white)); - painter.setPen(Qt::NoPen); - painter.drawRect(0, 0, width, height); + // Paint landscape + render(&painter, QRectF(0, 0, landRect.width(), landRect.height()), landRect); - render(&painter, QRectF(0, 0, width, height), - QRectF(regionMinX * m_cellSize, abs(regionMaxY) * m_cellSize, regionWidth * m_cellSize, regionHeight * m_cellSize)); - - image.save(fileName); - */ + QImage scaledImage = image.scaled(width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + scaledImage.save(fileName); } void LandscapeScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h index 7e60febaf..34fe50e05 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h @@ -57,8 +57,7 @@ public: void addZoneRegion(const NLLIGO::CZoneRegion &zoneRegion); void delZoneRegion(const NLLIGO::CZoneRegion &zoneRegion); - void snapshot(const QString &fileName, int sizeSource); - void snapshot(const QString &fileName, int width, int height); + void snapshot(const QString &fileName, int width, int height, const QRectF &landRect); protected: virtual void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/shapshot_dialog.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/shapshot_dialog.ui index 792d9f7a4..1c25a2ace 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/shapshot_dialog.ui +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/shapshot_dialog.ui @@ -6,8 +6,8 @@ 0 0 - 286 - 182 + 230 + 187 @@ -15,19 +15,33 @@ - - - Original size - - - true - - + + + + + Original size + + + true + + + + + + + 1024 + + + 128 + + + + - false + true Custom size @@ -59,7 +73,7 @@ false - TextLabel + Height: heightSpinBox @@ -82,7 +96,7 @@ - TextLabel + Width: widthSpinBox diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/snapshot_dialog.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/snapshot_dialog.cpp index ff6ef1673..ab2579722 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/snapshot_dialog.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/snapshot_dialog.cpp @@ -36,10 +36,36 @@ 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 */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/snapshot_dialog.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/snapshot_dialog.h index 906d59498..b66133a07 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/snapshot_dialog.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/snapshot_dialog.h @@ -34,6 +34,12 @@ public: SnapshotDialog(QWidget *parent = 0); ~SnapshotDialog(); + bool isCustomSize() const; + bool isKeepRatio() const; + int resolutionZone() const; + int widthSnapshot() const; + int heightSnapshot() const; + private Q_SLOTS: From d67fa1668dc738dea9691a0aa42794eb895e4d27 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Wed, 6 Jul 2011 18:52:10 +0300 Subject: [PATCH 19/89] Changed: #1301 Added dialog with a list of landscapes and operations (setActive, save, saveAs, delete). --HG-- branch : gsoc2011-worldeditorqt --- .../plugins/landscape_editor/builder_zone.cpp | 10 +- .../landscape_editor_window.cpp | 191 ++++++++++++++++-- .../landscape_editor_window.h | 11 + .../landscape_editor_window.ui | 81 +++++++- 4 files changed, 265 insertions(+), 28 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp index 265e380ca..9550b1f76 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp @@ -222,10 +222,11 @@ void ZoneBuilder::deleteZoneRegion(int id) { if ((0 <= id) && (id < int(m_landscapeItems.size()))) { + if (m_landscapeItems.at(id).rectItem != 0) + delete m_landscapeItems.at(id).rectItem; m_landscapeScene->delZoneRegion(m_landscapeItems.at(id).zoneRegionObject->ligoZoneRegion()); delete m_landscapeItems.at(id).zoneRegionObject; delete m_landscapeItems.at(id).builderZoneRegion; - delete m_landscapeItems.at(id).rectItem; m_landscapeItems.erase(m_landscapeItems.begin() + id); calcMask(); } @@ -236,10 +237,13 @@ void ZoneBuilder::setCurrentZoneRegion(int id) if ((0 <= id) && (id < int(m_landscapeItems.size()))) { if (currentIdZoneRegion() != -1) - m_landscapeItems.at(m_currentZoneRegion).rectItem = m_landscapeScene->createLayerBlackout(currentZoneRegion()->ligoZoneRegion()); - m_currentZoneRegion = id; + { + NLLIGO::CZoneRegion &ligoRegion = m_landscapeItems.at(m_currentZoneRegion).zoneRegionObject->ligoZoneRegion(); + m_landscapeItems.at(m_currentZoneRegion).rectItem = m_landscapeScene->createLayerBlackout(ligoRegion); + } delete m_landscapeItems.at(id).rectItem; m_landscapeItems.at(id).rectItem = 0; + m_currentZoneRegion = id; } } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp index 5f5fad552..da949fea5 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp @@ -33,15 +33,20 @@ // Qt includes #include +#include #include #include namespace LandscapeEditor { + +static const int LANDSCAPE_ID = 32; +int NewLandCounter = 0; QString _lastDir; LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent) : QMainWindow(parent), + m_currentRow(-1), m_landscapeScene(0), m_zoneBuilder(0), m_undoStack(0), @@ -53,7 +58,7 @@ LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent) m_landscapeScene = new LandscapeScene(this); m_zoneBuilder = new ZoneBuilder(m_landscapeScene, m_ui.zoneListWidget, m_undoStack); - m_zoneBuilder->init("e:/-nel-/install/continents/newbieland", true); + m_zoneBuilder->init("e:/-nel-/install/continents/newbieland", false); m_ui.zoneListWidget->setZoneBuilder(m_zoneBuilder); m_ui.zoneListWidget->updateUi(); @@ -63,6 +68,12 @@ LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent) m_oglWidget = new QGLWidget(QGLFormat(QGL::DoubleBuffer | QGL::SampleBuffers)); m_ui.graphicsView->setViewport(m_oglWidget); + 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.deleteLandAction->setEnabled(false); + createMenus(); createToolBars(); readSettings(); @@ -71,6 +82,16 @@ LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent) 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.landscapesListWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(customContextMenu())); + m_ui.landscapesListWidget->setContextMenuPolicy(Qt::CustomContextMenu); + } LandscapeEditorWindow::~LandscapeEditorWindow() @@ -97,17 +118,9 @@ void LandscapeEditorWindow::open() _lastDir = QFileInfo(list.front()).absolutePath(); Q_FOREACH(QString fileName, fileNames) { - int id = m_zoneBuilder->createZoneRegion(fileName); - if (id == -1) - { - QMessageBox::critical(this, "Landscape Editor", "Cannot add this zone because it overlaps existing ones"); - continue; - } - ZoneRegionObject *zoneRegion = m_zoneBuilder->zoneRegion(id); - m_ui.graphicsView->centerOn(zoneRegion->ligoZoneRegion().getMinX() * m_landscapeScene->cellSize(), - abs(zoneRegion->ligoZoneRegion().getMinY()) * m_landscapeScene->cellSize()); - - m_zoneBuilder->setCurrentZoneRegion(id); + int row = createLandscape(fileName); + if (row != -1) + setActiveLandscape(row); } } setCursor(Qt::ArrowCursor); @@ -115,16 +128,7 @@ void LandscapeEditorWindow::open() void LandscapeEditorWindow::save() { - ZoneRegionObject *zoneRegion = m_zoneBuilder->currentZoneRegion(); - if (zoneRegion->fileName().empty()) - { - QString fileName = QFileDialog::getSaveFileName(this, - tr("Save NeL Ligo land file"), _lastDir, - tr("NeL Ligo land file (*.land)")); - if (!fileName.isEmpty()) - zoneRegion->setFileName(fileName.toStdString()); - } - zoneRegion->save(); + saveLandscape(m_currentRow, true); } void LandscapeEditorWindow::openProjectSettings() @@ -184,6 +188,133 @@ void LandscapeEditorWindow::openSnapshotDialog() 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() +{ + createLandscape(QString()); +} + +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(); + QListWidgetItem *item = m_ui.landscapesListWidget->item(row); + if (row == m_currentRow) + { + 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); +} + +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_currentRow != -1) + { + QListWidgetItem *item = m_ui.landscapesListWidget->item(m_currentRow); + item->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_currentRow = row; + } +} + +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); @@ -202,7 +333,23 @@ void LandscapeEditorWindow::createToolBars() //QAction *action = menuManager->action(Core::Constants::NEW); //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); + + const char * const UNDO = "ObjectViewerQt.Undo"; + const char * const REDO = "ObjectViewerQt.Redo"; + + //action = menuManager->action(Core::Constants::UNDO); + action = menuManager->action(UNDO); + if (action != 0) + m_ui.undoToolBar->addAction(action); + + //action = menuManager->action(Core::Constants::REDO); + action = menuManager->action(REDO); + if (action != 0) + m_ui.undoToolBar->addAction(action); + //action = menuManager->action(Core::Constants::SAVE); //m_ui.fileToolBar->addAction(action); //action = menuManager->action(Core::Constants::SAVE_AS); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h index ff9cfd273..f3421f120 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h @@ -49,6 +49,12 @@ public Q_SLOTS: private Q_SLOTS: void openProjectSettings(); void openSnapshotDialog(); + void customContextMenu(); + void newLand(); + void setActiveLand(); + void saveSelectedLand(); + void saveAsSelectedLand(); + void deleteSelectedLand(); protected: virtual void showEvent(QShowEvent *showEvent); @@ -59,6 +65,11 @@ private: void readSettings(); void writeSettings(); + void setActiveLandscape(int row); + void saveLandscape(int row, bool force); + int createLandscape(const QString &fileName); + + int m_currentRow; LandscapeScene *m_landscapeScene; ZoneBuilder *m_zoneBuilder; QUndoStack *m_undoStack; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui index 57eadda73..7d71acd49 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui @@ -62,7 +62,7 @@ - + toolBar_2 @@ -72,9 +72,40 @@ false - - + + + + Landscapes + + + 1 + + + + + 3 + + + 3 + + + + + + + + + + toolBar + + + TopToolBarArea + + + false + + @@ -113,6 +144,50 @@ Save + + + + :/icons/ic_nel_zone.png:/icons/ic_nel_zone.png + + + Set active + + + Set active selected landscape + + + + + Save + + + Save selected landscape + + + + + Save As landscape + + + Save as selected landscape + + + + + Delete + + + Delete selected landscape + + + + + New + + + Create new landscape + + From 415ad3e594ec2952e9efb6306ad81765bfae30c6 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Mon, 11 Jul 2011 00:23:28 +0300 Subject: [PATCH 20/89] Changed: #1302 Added basic shell of World editor plugin. --HG-- branch : gsoc2011-worldeditorqt --- .../src/plugins/world_editor/CMakeLists.txt | 48 +++++++ .../icons/ic_nel_world_editor.png | Bin 0 -> 44031 bytes .../src/plugins/world_editor/world_editor.qrc | 5 + .../world_editor/world_editor_constants.h | 39 ++++++ .../world_editor/world_editor_global.h | 30 ++++ .../world_editor/world_editor_plugin.cpp | 128 ++++++++++++++++++ .../world_editor/world_editor_plugin.h | 108 +++++++++++++++ .../world_editor/world_editor_window.cpp | 119 ++++++++++++++++ .../world_editor/world_editor_window.h | 57 ++++++++ .../world_editor/world_editor_window.ui | 54 ++++++++ 10 files changed, 588 insertions(+) create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/CMakeLists.txt create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/icons/ic_nel_world_editor.png create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor.qrc create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_constants.h create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_global.h create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_plugin.cpp create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_plugin.h create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/CMakeLists.txt new file mode 100644 index 000000000..784dd6139 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/CMakeLists.txt @@ -0,0 +1,48 @@ +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 +) + +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) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/icons/ic_nel_world_editor.png b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/icons/ic_nel_world_editor.png new file mode 100644 index 0000000000000000000000000000000000000000..d41f64e2fa43da9d64f9b528cc173593d4a94c59 GIT binary patch literal 44031 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 GHST}F+s82g literal 0 HcmV?d00001 diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor.qrc b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor.qrc new file mode 100644 index 000000000..f7c54fd5f --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor.qrc @@ -0,0 +1,5 @@ + + + icons/ic_nel_world_editor.png + + diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_constants.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_constants.h new file mode 100644 index 000000000..644f79b53 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_constants.h @@ -0,0 +1,39 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +#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"; + +//resources +const char * const ICON_WORLD_EDITOR = ":/icons/ic_nel_world_editor.png"; + + +} // namespace Constants +} // namespace WorldEditor + +#endif // WORLD_EDITOR_CONSTANTS_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_global.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_global.h new file mode 100644 index 000000000..a7a94ca75 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_global.h @@ -0,0 +1,30 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// 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 . + +#ifndef WORLD_EDITOR_GLOBAL_H +#define WORLD_EDITOR_GLOBAL_H + +#include + +#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 diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_plugin.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_plugin.cpp new file mode 100644 index 000000000..494f6e2b6 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_plugin.cpp @@ -0,0 +1,128 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +// 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" + +// Qt includes +#include + +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) +{ + Q_UNUSED(errorString); + m_plugMan = pluginManager; + + 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) \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_plugin.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_plugin.h new file mode 100644 index 000000000..fdfff7eff --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_plugin.h @@ -0,0 +1,108 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +#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" + +// Qt includes +#include +#include + +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: + ExtensionSystem::IPluginManager *m_plugMan; + QList 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 diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp new file mode 100644 index 000000000..7d6f9dcfd --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp @@ -0,0 +1,119 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +// Project includes +#include "world_editor_window.h" +#include "world_editor_constants.h" + +#include "../core/icore.h" +#include "../core/imenu_manager.h" +#include "../core/core_constants.h" + +// Qt includes +#include + +namespace WorldEditor +{ +QString _lastDir; + +WorldEditorWindow::WorldEditorWindow(QWidget *parent) + : QMainWindow(parent), + m_undoStack(0) +{ + m_ui.setupUi(this); + m_undoStack = new QUndoStack(this); + + createMenus(); + createToolBars(); +// readSettings(); +} + +WorldEditorWindow::~WorldEditorWindow() +{ +// writeSettings(); +} + +QUndoStack *WorldEditorWindow::undoStack() const +{ + return m_undoStack; +} + +void WorldEditorWindow::open() +{ + /* QStringList fileNames = QFileDialog::getOpenFileNames(this, + tr("Open NeL Ligo land file"), _lastDir, + tr("All NeL Ligo land files (*.land)")); + + setCursor(Qt::WaitCursor); + if (!fileNames.isEmpty()) + { + QStringList list = fileNames; + _lastDir = QFileInfo(list.front()).absolutePath(); + Q_FOREACH(QString fileName, fileNames) + { + } + } + setCursor(Qt::ArrowCursor);*/ +} + +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); + QAction *action = menuManager->action(Core::Constants::OPEN); + m_ui.fileToolBar->addAction(action); + + action = menuManager->action(Core::Constants::UNDO); + if (action != 0) + m_ui.undoToolBar->addAction(action); + + action = menuManager->action(Core::Constants::REDO); + if (action != 0) + m_ui.undoToolBar->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 */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h new file mode 100644 index 000000000..8efafc48b --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h @@ -0,0 +1,57 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +#ifndef WORLD_EDITOR_WINDOW_H +#define WORLD_EDITOR_WINDOW_H + +// Project includes +#include "ui_world_editor_window.h" + +// Qt includes +#include + +namespace WorldEditor +{ + +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: +private: + void createMenus(); + void createToolBars(); + void readSettings(); + void writeSettings(); + + QUndoStack *m_undoStack; + Ui::WorldEditorWindow m_ui; +}; /* class WorldEditorWindow */ + +} /* namespace WorldEditor */ + +#endif // WORLD_EDITOR_WINDOW_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui new file mode 100644 index 000000000..86c8a2b11 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui @@ -0,0 +1,54 @@ + + + WorldEditorWindow + + + + 0 + 0 + 800 + 600 + + + + MainWindow + + + + :/icons/ic_nel_world_editor.png:/icons/ic_nel_world_editor.png + + + + + + + + + + + toolBar + + + TopToolBarArea + + + false + + + + + toolBar + + + TopToolBarArea + + + false + + + + + + + + From 13ddd2d01b316bd8ff58a5020d5abb06462cd7bf Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Mon, 11 Jul 2011 02:06:14 +0300 Subject: [PATCH 21/89] Changed: #1301 Improved Landscape plugin. --HG-- branch : gsoc2011-worldeditorqt --- .../src/plugins/CMakeLists.txt | 1 + .../plugins/landscape_editor/CMakeLists.txt | 2 +- .../plugins/landscape_editor/builder_zone.cpp | 129 +++++++++--------- .../plugins/landscape_editor/builder_zone.h | 4 +- .../landscape_editor_plugin.cpp | 2 +- .../landscape_editor_window.cpp | 34 ++--- .../landscape_editor_window.h | 2 +- .../landscape_editor_window.ui | 12 ++ .../landscape_editor/landscape_scene.cpp | 48 ++++++- .../landscape_editor/landscape_scene.h | 3 + 10 files changed, 138 insertions(+), 99 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/plugins/CMakeLists.txt index bec71cf94..880f49c74 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/CMakeLists.txt +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/CMakeLists.txt @@ -7,3 +7,4 @@ ADD_SUBDIRECTORY(disp_sheet_id) ADD_SUBDIRECTORY(object_viewer) ADD_SUBDIRECTORY(zone_painter) ADD_SUBDIRECTORY(georges_editor) +ADD_SUBDIRECTORY(world_editor) \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt index 2f1d58c66..7ef0a11bf 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt @@ -40,7 +40,7 @@ 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} diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp index 9550b1f76..b9ffe7151 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp @@ -26,11 +26,11 @@ // Qt includes #include #include -#include #include namespace LandscapeEditor { +int LandCounter = 0; ZoneBuilder::ZoneBuilder(LandscapeScene *landscapeScene, ListZonesWidget *listZonesWidget, QUndoStack *undoStack) : m_currentZoneRegion(-1), @@ -117,7 +117,7 @@ void ZoneBuilder::addZone(sint32 posX, sint32 posY) if ((m_listZonesWidget == 0) || (m_undoStack == 0)) return; - if (m_landscapeItems.empty()) + if (m_landscapeMap.empty()) return; // Check zone name @@ -125,7 +125,7 @@ void ZoneBuilder::addZone(sint32 posX, sint32 posY) if (zoneName.empty()) return; - BuilderZoneRegion *builderZoneRegion = m_landscapeItems.at(m_currentZoneRegion).builderZoneRegion; + BuilderZoneRegion *builderZoneRegion = m_landscapeMap.value(m_currentZoneRegion).builderZoneRegion; builderZoneRegion->init(this); uint8 rot = uint8(m_listZonesWidget->currentRot()); @@ -161,13 +161,13 @@ void ZoneBuilder::delZone(const sint32 posX, const sint32 posY) if ((m_listZonesWidget == 0) || (m_undoStack == 0)) return; - if (m_landscapeItems.empty()) + if (m_landscapeMap.empty()) return; m_titleAction = QString("Del zone %1,%2").arg(posX).arg(posY); m_createdAction = false; - BuilderZoneRegion *builderZoneRegion = m_landscapeItems.at(m_currentZoneRegion).builderZoneRegion; + BuilderZoneRegion *builderZoneRegion = m_landscapeMap.value(m_currentZoneRegion).builderZoneRegion; builderZoneRegion->init(this); builderZoneRegion->del(posX, posY); @@ -176,24 +176,22 @@ void ZoneBuilder::delZone(const sint32 posX, const sint32 posY) int ZoneBuilder::createZoneRegion() { - int newId = m_landscapeItems.size(); LandscapeItem landItem; landItem.zoneRegionObject = new ZoneRegionObject(); - landItem.builderZoneRegion = new BuilderZoneRegion(newId); + landItem.builderZoneRegion = new BuilderZoneRegion(LandCounter); landItem.builderZoneRegion->init(this); - landItem.rectItem = 0; + landItem.rectItem = m_landscapeScene->createLayerBlackout(landItem.zoneRegionObject->ligoZoneRegion()); - newZone(); - m_landscapeItems.push_back(landItem); + m_landscapeMap.insert(LandCounter, landItem); if (m_currentZoneRegion == -1) - setCurrentZoneRegion(newId); + setCurrentZoneRegion(LandCounter); - return newId; + calcMask(); + return LandCounter++; } int ZoneBuilder::createZoneRegion(const QString &fileName) { - int newId = m_landscapeItems.size(); LandscapeItem landItem; landItem.zoneRegionObject = new ZoneRegionObject(); landItem.zoneRegionObject->load(fileName.toStdString()); @@ -203,48 +201,52 @@ int ZoneBuilder::createZoneRegion(const QString &fileName) delete landItem.zoneRegionObject; return -1; } - landItem.builderZoneRegion = new BuilderZoneRegion(newId); + landItem.builderZoneRegion = new BuilderZoneRegion(LandCounter); landItem.builderZoneRegion->init(this); - newZone(); - m_landscapeItems.push_back(landItem); - m_landscapeScene->addZoneRegion(landItem.zoneRegionObject->ligoZoneRegion()); - m_landscapeItems.at(newId).rectItem = m_landscapeScene->createLayerBlackout(landItem.zoneRegionObject->ligoZoneRegion()); + landItem.rectItem = m_landscapeScene->createLayerBlackout(landItem.zoneRegionObject->ligoZoneRegion()); + m_landscapeMap.insert(LandCounter, landItem); if (m_currentZoneRegion == -1) - setCurrentZoneRegion(newId); + setCurrentZoneRegion(LandCounter); - return newId; + calcMask(); + return LandCounter++; } void ZoneBuilder::deleteZoneRegion(int id) { - if ((0 <= id) && (id < int(m_landscapeItems.size()))) + if (m_landscapeMap.contains(id)) { - if (m_landscapeItems.at(id).rectItem != 0) - delete m_landscapeItems.at(id).rectItem; - m_landscapeScene->delZoneRegion(m_landscapeItems.at(id).zoneRegionObject->ligoZoneRegion()); - delete m_landscapeItems.at(id).zoneRegionObject; - delete m_landscapeItems.at(id).builderZoneRegion; - m_landscapeItems.erase(m_landscapeItems.begin() + 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 ((0 <= id) && (id < int(m_landscapeItems.size()))) + if (m_landscapeMap.contains(id)) { if (currentIdZoneRegion() != -1) { - NLLIGO::CZoneRegion &ligoRegion = m_landscapeItems.at(m_currentZoneRegion).zoneRegionObject->ligoZoneRegion(); - m_landscapeItems.at(m_currentZoneRegion).rectItem = m_landscapeScene->createLayerBlackout(ligoRegion); + NLLIGO::CZoneRegion &ligoRegion = m_landscapeMap.value(m_currentZoneRegion).zoneRegionObject->ligoZoneRegion(); + m_landscapeMap[m_currentZoneRegion].rectItem = m_landscapeScene->createLayerBlackout(ligoRegion); } - delete m_landscapeItems.at(id).rectItem; - m_landscapeItems.at(id).rectItem = 0; + 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 @@ -254,27 +256,27 @@ int ZoneBuilder::currentIdZoneRegion() const ZoneRegionObject *ZoneBuilder::currentZoneRegion() const { - return m_landscapeItems.at(m_currentZoneRegion).zoneRegionObject; + return m_landscapeMap.value(m_currentZoneRegion).zoneRegionObject; } int ZoneBuilder::countZoneRegion() const { - return m_landscapeItems.size(); + return m_landscapeMap.size(); } ZoneRegionObject *ZoneBuilder::zoneRegion(int id) const { - return m_landscapeItems.at(id).zoneRegionObject; + return m_landscapeMap.value(id).zoneRegionObject; } void ZoneBuilder::ligoData(LigoData &data, const ZonePosition &zonePos) { - m_landscapeItems.at(zonePos.region).zoneRegionObject->ligoData(data, zonePos.x, zonePos.y); + m_landscapeMap.value(zonePos.region).zoneRegionObject->ligoData(data, zonePos.x, zonePos.y); } void ZoneBuilder::setLigoData(LigoData &data, const ZonePosition &zonePos) { - m_landscapeItems.at(zonePos.region).zoneRegionObject->setLigoData(data, zonePos.x, zonePos.y); + m_landscapeMap.value(zonePos.region).zoneRegionObject->setLigoData(data, zonePos.x, zonePos.y); } bool ZoneBuilder::initZoneBank (const QString &pathName) @@ -307,25 +309,6 @@ QString ZoneBuilder::dataPath() const return m_lastPathName; } -void ZoneBuilder::newZone() -{ - // Select starting point for the moment 0,0 - sint32 x = 0, y = 0; - - // If there are some zone already present increase x until free - for (size_t i = 0; i < m_landscapeItems.size(); ++i) - { - const NLLIGO::CZoneRegion &zoneRegion = m_landscapeItems.at(i).zoneRegionObject->ligoZoneRegion(); - const std::string &zoneName = zoneRegion.getName (x, y); - if ((zoneName != STRING_OUT_OF_BOUND) && (zoneName != STRING_UNUSED)) - { - ++x; - i = -1; - } - } - calcMask(); -} - bool ZoneBuilder::getZoneMask(sint32 x, sint32 y) { if ((x < m_minX) || (x > m_maxX) || @@ -346,12 +329,14 @@ void ZoneBuilder::calcMask() m_minY = m_minX = 1000000; m_maxY = m_maxX = -1000000; - if (m_landscapeItems.size() == 0) + if (m_landscapeMap.size() == 0) return; - for (size_t i = 0; i < m_landscapeItems.size(); ++i) + QMapIterator i(m_landscapeMap); + while (i.hasNext()) { - const NLLIGO::CZoneRegion ®ion = m_landscapeItems.at(i).zoneRegionObject->ligoZoneRegion(); + i.next(); + const NLLIGO::CZoneRegion ®ion = i.value().zoneRegionObject->ligoZoneRegion(); if (m_minX > region.getMinX()) m_minX = region.getMinX(); @@ -370,10 +355,13 @@ void ZoneBuilder::calcMask() { m_zoneMask[x - m_minX + (y - m_minY) * stride] = true; - for (size_t i = 0; i < m_landscapeItems.size(); ++i) - if (int(i) != m_currentZoneRegion) + QMapIterator it(m_landscapeMap); + while (it.hasNext()) + { + it.next(); + if (int(it.key()) != m_currentZoneRegion) { - const NLLIGO::CZoneRegion ®ion = zoneRegion(i)->ligoZoneRegion(); + const NLLIGO::CZoneRegion ®ion = it.value().zoneRegionObject->ligoZoneRegion(); const std::string &rSZone = region.getName (x, y); if ((rSZone != STRING_OUT_OF_BOUND) && (rSZone != STRING_UNUSED)) @@ -381,21 +369,24 @@ void ZoneBuilder::calcMask() m_zoneMask[x - m_minX + (y - m_minY) * stride] = false; } } + } } } bool ZoneBuilder::getZoneAmongRegions(ZonePosition &zonePos, BuilderZoneRegion *builderZoneRegionFrom, sint32 x, sint32 y) { - for (size_t i = 0; i < m_landscapeItems.size(); ++i) + QMapIterator it(m_landscapeMap); + while (it.hasNext()) { - const NLLIGO::CZoneRegion ®ion = m_landscapeItems.at(i).zoneRegionObject->ligoZoneRegion(); + it.next(); + const NLLIGO::CZoneRegion ®ion = it.value().zoneRegionObject->ligoZoneRegion(); if ((x < region.getMinX()) || (x > region.getMaxX()) || (y < region.getMinY()) || (y > region.getMaxY())) continue; if (region.getName(x, y) != STRING_UNUSED) { - builderZoneRegionFrom = m_landscapeItems.at(i).builderZoneRegion; - zonePos = ZonePosition(x, y, i); + builderZoneRegionFrom = it.value().builderZoneRegion; + zonePos = ZonePosition(x, y, it.key()); return true; } } @@ -435,9 +426,11 @@ void ZoneBuilder::checkEndMacro() bool ZoneBuilder::checkOverlaps(const NLLIGO::CZoneRegion &newZoneRegion) { - for (size_t j = 0; j < m_landscapeItems.size(); ++j) + QMapIterator it(m_landscapeMap); + while (it.hasNext()) { - const NLLIGO::CZoneRegion &zoneRegion = m_landscapeItems.at(j).zoneRegionObject->ligoZoneRegion(); + 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) { diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h index 17d5a6f7e..5fbd80832 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h @@ -85,7 +85,6 @@ public: bool init(const QString &pathName, bool bMakeAZone); void calcMask(); - void newZone(); bool getZoneMask (sint32 x, sint32 y); bool getZoneAmongRegions(ZonePosition &zonePos, BuilderZoneRegion *builderZoneRegionFrom, sint32 x, sint32 y); @@ -150,7 +149,8 @@ private: QString m_lastPathName; int m_currentZoneRegion; - std::vector m_landscapeItems; + //std::vector m_landscapeItems; + QMap m_landscapeMap; bool m_createdAction; QString m_titleAction; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_plugin.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_plugin.cpp index ac7782343..401256ce6 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_plugin.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_plugin.cpp @@ -75,7 +75,7 @@ QString LandscapeEditorPlugin::name() const QString LandscapeEditorPlugin::version() const { - return "0.0.1"; + return "0.1"; } QString LandscapeEditorPlugin::vendor() const diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp index da949fea5..4dd3163ba 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp @@ -46,7 +46,7 @@ QString _lastDir; LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent) : QMainWindow(parent), - m_currentRow(-1), + m_currentItem(0), m_landscapeScene(0), m_zoneBuilder(0), m_undoStack(0), @@ -65,8 +65,7 @@ LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent) m_landscapeScene->setZoneBuilder(m_zoneBuilder); m_ui.graphicsView->setScene(m_landscapeScene); //m_oglWidget = new QGLWidget(QGLFormat(QGL::DoubleBuffer)); - m_oglWidget = new QGLWidget(QGLFormat(QGL::DoubleBuffer | QGL::SampleBuffers)); - m_ui.graphicsView->setViewport(m_oglWidget); + //m_ui.graphicsView->setViewport(m_oglWidget); m_ui.newLandAction->setIcon(QIcon(Core::Constants::ICON_NEW)); m_ui.saveAction->setIcon(QIcon(Core::Constants::ICON_SAVE)); @@ -128,7 +127,7 @@ void LandscapeEditorWindow::open() void LandscapeEditorWindow::save() { - saveLandscape(m_currentRow, true); + saveLandscape(m_ui.landscapesListWidget->row(m_currentItem), true); } void LandscapeEditorWindow::openProjectSettings() @@ -203,7 +202,9 @@ void LandscapeEditorWindow::customContextMenu() void LandscapeEditorWindow::newLand() { - createLandscape(QString()); + int row = createLandscape(QString()); + if (row != -1) + setActiveLandscape(row); } void LandscapeEditorWindow::setActiveLand() @@ -224,8 +225,9 @@ void LandscapeEditorWindow::saveAsSelectedLand() 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 == m_currentRow) + if (row == current_row) { if (row == 0) ++row; @@ -236,6 +238,7 @@ void LandscapeEditorWindow::deleteSelectedLand() 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); } @@ -276,15 +279,13 @@ void LandscapeEditorWindow::setActiveLandscape(int row) { if ((0 <= row) && (row < m_ui.landscapesListWidget->count())) { - if (m_currentRow != -1) - { - QListWidgetItem *item = m_ui.landscapesListWidget->item(m_currentRow); - item->setFont(QFont("SansSerif", 9, QFont::Normal)); - } + 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_currentRow = row; + m_currentItem = item; } } @@ -337,16 +338,11 @@ void LandscapeEditorWindow::createToolBars() m_ui.fileToolBar->addAction(action); m_ui.fileToolBar->addAction(m_ui.saveAction); - const char * const UNDO = "ObjectViewerQt.Undo"; - const char * const REDO = "ObjectViewerQt.Redo"; - - //action = menuManager->action(Core::Constants::UNDO); - action = menuManager->action(UNDO); + action = menuManager->action(Core::Constants::UNDO); if (action != 0) m_ui.undoToolBar->addAction(action); - //action = menuManager->action(Core::Constants::REDO); - action = menuManager->action(REDO); + action = menuManager->action(Core::Constants::REDO); if (action != 0) m_ui.undoToolBar->addAction(action); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h index f3421f120..18ce670b7 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h @@ -69,7 +69,7 @@ private: void saveLandscape(int row, bool force); int createLandscape(const QString &fileName); - int m_currentRow; + QListWidgetItem *m_currentItem; LandscapeScene *m_landscapeScene; ZoneBuilder *m_zoneBuilder; QUndoStack *m_undoStack; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui index 7d71acd49..b2db9dc42 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui @@ -38,6 +38,18 @@ QGraphicsView::NoDrag + + QGraphicsView::AnchorUnderMouse + + + QGraphicsView::AnchorUnderMouse + + + QGraphicsView::FullViewportUpdate + + + QGraphicsView::DontSavePainterState + diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp index 81a94fb1f..3b10d4fed 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp @@ -26,6 +26,7 @@ #include #include #include +#include namespace LandscapeEditor { @@ -34,11 +35,13 @@ 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"; LandscapeScene::LandscapeScene(QObject *parent) : QGraphicsScene(parent), m_mouseX(0.0), m_mouseY(0.0), + m_mouseButton(Qt::NoButton), m_zoneBuilder(0) { m_cellSize = 160; @@ -154,7 +157,7 @@ QGraphicsItem *LandscapeScene::createItemZone(const LigoData &data, const ZonePo // 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())); + item->setData(ZONE_NAME, QString(data.zoneName.c_str())); // for not full item zone item->setZValue(LAYER_ZONES); @@ -198,13 +201,14 @@ QGraphicsRectItem *LandscapeScene::createLayerBlackout(const NLLIGO::CZoneRegion 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) + if ((item != 0) && (item->data(ZONE_NAME).toString() != QString(LAYER_BLACKOUT_NAME))) { removeItem(item); delete item; @@ -282,30 +286,60 @@ void LandscapeScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) if ((x < 0) || (y < 0)) return; - sint32 posX = sint32(floor(x / m_cellSize)); - sint32 posY = sint32(-floor(y / m_cellSize)); + m_posX = sint32(floor(x / m_cellSize)); + m_posY = sint32(-floor(y / m_cellSize)); if (mouseEvent->button() == Qt::LeftButton) - m_zoneBuilder->addZone(posX, posY); + m_zoneBuilder->addZone(m_posX, m_posY); else if (mouseEvent->button() == Qt::RightButton) - m_zoneBuilder->delZone(posX, posY); + m_zoneBuilder->delZone(m_posX, m_posY); + + m_mouseButton = mouseEvent->button(); QGraphicsScene::mousePressEvent(mouseEvent); } void LandscapeScene::mouseMoveEvent(QGraphicsSceneMouseEvent * mouseEvent) { + qreal x = mouseEvent->scenePos().rx(); + qreal y = mouseEvent->scenePos().ry(); + + 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_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_mouseX = mouseEvent->scenePos().x(); m_mouseY = mouseEvent->scenePos().y(); 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) { - return true; + if (item->data(ZONE_NAME) == QString(LAYER_BLACKOUT_NAME)) + return false; + else + return true; } return false; } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h index 34fe50e05..39f81bf98 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h @@ -62,6 +62,7 @@ public: protected: virtual void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent); virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent); virtual void drawForeground(QPainter *painter, const QRectF &rect); private: @@ -69,6 +70,8 @@ private: int m_cellSize; qreal m_mouseX, m_mouseY; + sint32 m_posX, m_posY; + Qt::MouseButton m_mouseButton; ZoneBuilder *m_zoneBuilder; }; From 018fcac076950fd2ef09bf0aae4c7d0bf81a7830 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Tue, 12 Jul 2011 01:14:25 +0300 Subject: [PATCH 22/89] Changed: #1301 Removed a hard coded value. --HG-- branch : gsoc2011-worldeditorqt --- .../plugins/landscape_editor/builder_zone.cpp | 15 +++++++------- .../plugins/landscape_editor/builder_zone.h | 2 +- .../landscape_editor_constants.h | 2 ++ .../landscape_editor_window.cpp | 20 ++++++++++++++----- 4 files changed, 25 insertions(+), 14 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp index b9ffe7151..cb97c20ea 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp @@ -49,9 +49,10 @@ ZoneBuilder::~ZoneBuilder() delete m_pixmapDatabase; } -bool ZoneBuilder::init(const QString &pathName, bool makeAZone) +bool ZoneBuilder::init(const QString &pathName, bool displayProgress) { - bool bRet = true; + if (pathName.isEmpty()) + return false; if (pathName != m_lastPathName) { m_lastPathName = pathName; @@ -59,25 +60,23 @@ bool ZoneBuilder::init(const QString &pathName, bool makeAZone) zoneBankPath += "/zoneligos/"; // Init the ZoneBank - m_zoneBank.reset (); + m_zoneBank.reset(); if (!initZoneBank (zoneBankPath)) { - m_zoneBank.reset (); + 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)) + if (!m_pixmapDatabase->loadPixmaps(zoneBitmapPath, m_zoneBank, displayProgress)) { m_zoneBank.reset(); return false; } } - if ((makeAZone) && (bRet)) - createZoneRegion(); - return bRet; + return true; } void ZoneBuilder::actionLigoTile(const LigoData &data, const ZonePosition &zonePos) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h index 5fbd80832..213ba9b13 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h @@ -82,7 +82,7 @@ public: ~ZoneBuilder(); /// Init zoneBank and init zone pixmap database - bool init(const QString &pathName, bool bMakeAZone); + bool init(const QString &pathName, bool displayProgress = false); void calcMask(); bool getZoneMask (sint32 x, sint32 y); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_constants.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_constants.h index 6875ddfab..9ab2dbfbc 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_constants.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_constants.h @@ -28,6 +28,8 @@ const char * const LANDSCAPE_EDITOR_PLUGIN = "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"; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp index 4dd3163ba..3483766f9 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp @@ -58,14 +58,11 @@ LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent) m_landscapeScene = new LandscapeScene(this); m_zoneBuilder = new ZoneBuilder(m_landscapeScene, m_ui.zoneListWidget, m_undoStack); - m_zoneBuilder->init("e:/-nel-/install/continents/newbieland", false); m_ui.zoneListWidget->setZoneBuilder(m_zoneBuilder); m_ui.zoneListWidget->updateUi(); m_landscapeScene->setZoneBuilder(m_zoneBuilder); m_ui.graphicsView->setScene(m_landscapeScene); - //m_oglWidget = new QGLWidget(QGLFormat(QGL::DoubleBuffer)); - //m_ui.graphicsView->setViewport(m_oglWidget); m_ui.newLandAction->setIcon(QIcon(Core::Constants::ICON_NEW)); m_ui.saveAction->setIcon(QIcon(Core::Constants::ICON_SAVE)); @@ -95,8 +92,8 @@ LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent) LandscapeEditorWindow::~LandscapeEditorWindow() { - delete m_zoneBuilder; writeSettings(); + delete m_zoneBuilder; } QUndoStack *LandscapeEditorWindow::undoStack() const @@ -137,7 +134,7 @@ void LandscapeEditorWindow::openProjectSettings() int ok = dialog->exec(); if (ok == QDialog::Accepted) { - m_zoneBuilder->init(dialog->dataPath(), false); + m_zoneBuilder->init(dialog->dataPath(), true); m_ui.zoneListWidget->updateUi(); } delete dialog; @@ -358,6 +355,18 @@ void LandscapeEditorWindow::readSettings() 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(); } @@ -367,6 +376,7 @@ void LandscapeEditorWindow::writeSettings() 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(); } From a5749c75f5bd0c5ad142e3c7da037fa2dda937d5 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Wed, 13 Jul 2011 03:34:45 +0300 Subject: [PATCH 23/89] Changed: #1301 Added status info and each zone tile has small text in graphics view. --HG-- branch : gsoc2011-worldeditorqt --- .../landscape_editor_window.cpp | 21 +++++++++++ .../landscape_editor_window.h | 7 ++++ .../landscape_editor/landscape_scene.cpp | 35 +++++++++++++------ .../landscape_editor/landscape_scene.h | 2 ++ .../landscape_editor/landscape_view.cpp | 21 +++++++++++ 5 files changed, 75 insertions(+), 11 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp index 3483766f9..662c1d9c9 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp @@ -36,6 +36,7 @@ #include #include #include +#include namespace LandscapeEditor { @@ -88,6 +89,12 @@ LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent) 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() @@ -318,6 +325,20 @@ 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() diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h index 18ce670b7..67768e39a 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h @@ -24,6 +24,8 @@ // Qt includes #include #include +#include +#include namespace LandscapeEditor { @@ -50,6 +52,7 @@ private Q_SLOTS: void openProjectSettings(); void openSnapshotDialog(); void customContextMenu(); + void updateStatusBar(); void newLand(); void setActiveLand(); void saveSelectedLand(); @@ -58,6 +61,7 @@ private Q_SLOTS: protected: virtual void showEvent(QShowEvent *showEvent); + virtual void hideEvent(QHideEvent *hideEvent); private: void createMenus(); @@ -69,6 +73,9 @@ private: 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; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp index 3b10d4fed..b2dc9dd5d 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp @@ -39,8 +39,6 @@ const char * const LAYER_BLACKOUT_NAME = "blackout"; LandscapeScene::LandscapeScene(QObject *parent) : QGraphicsScene(parent), - m_mouseX(0.0), - m_mouseY(0.0), m_mouseButton(Qt::NoButton), m_zoneBuilder(0) { @@ -170,6 +168,9 @@ 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) @@ -276,11 +277,17 @@ void LandscapeScene::snapshot(const QString &fileName, int width, int height, co scaledImage.save(fileName); } -void LandscapeScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) +QString LandscapeScene::zoneNameFromMousePos() const { - if (m_zoneBuilder == 0) - return; + if ((m_posY > 0) || (m_posY < -255) || + (m_posX < 0) || (m_posX > 255)) + return "NOT A VALID ZONE"; + + return QString("%1_%2%3").arg(-m_posY).arg(QChar('A' + (m_posX/26))).arg(QChar('A' + (m_posX%26))); +} +void LandscapeScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) +{ qreal x = mouseEvent->scenePos().rx(); qreal y = mouseEvent->scenePos().ry(); if ((x < 0) || (y < 0)) @@ -289,6 +296,9 @@ void LandscapeScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) m_posX = sint32(floor(x / m_cellSize)); m_posY = sint32(-floor(y / m_cellSize)); + if (m_zoneBuilder == 0) + return; + if (mouseEvent->button() == Qt::LeftButton) m_zoneBuilder->addZone(m_posX, m_posY); else if (mouseEvent->button() == Qt::RightButton) @@ -321,8 +331,11 @@ void LandscapeScene::mouseMoveEvent(QGraphicsSceneMouseEvent * mouseEvent) QApplication::processEvents(); } - m_mouseX = mouseEvent->scenePos().x(); - m_mouseY = mouseEvent->scenePos().y(); + m_posX = posX; + m_posY = posY; + + m_mouseX = mouseEvent->scenePos().rx(); + m_mouseY = mouseEvent->scenePos().ry(); QGraphicsScene::mouseMoveEvent(mouseEvent); } @@ -336,10 +349,10 @@ 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; + //if (item->data(ZONE_NAME) == QString(LAYER_BLACKOUT_NAME)) + // return false; + //else + return true; } return false; } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h index 39f81bf98..71d4c512e 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h @@ -59,6 +59,8 @@ public: void snapshot(const QString &fileName, int width, int height, const QRectF &landRect); + QString zoneNameFromMousePos() const; + protected: virtual void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent); virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp index 84bc4b47d..40074292d 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp @@ -137,6 +137,27 @@ void LandscapeView::drawForeground(QPainter *painter, const QRectF &rect) painter->drawLine(int(rect.left()), int(top), int(rect.right()), int(top)); top += m_cellSize; } + + // Render text (slow!) + if (m_numSteps > -m_maxSteps / 4) + { + painter->setPen(QPen(Qt::white, 0.5, Qt::SolidLine)); + + //painter->setFont(QFont("Helvetica [Cronyx]", 12)); + 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 */ From e054d87d015f5f445ddf6f184b79be4a9c8035c3 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Wed, 13 Jul 2011 04:49:09 +0300 Subject: [PATCH 24/89] Fixed: #1301 A temporary fix instead of the future of undo command delete landscape. --HG-- branch : gsoc2011-worldeditorqt --- .../src/plugins/landscape_editor/landscape_editor_window.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp index 662c1d9c9..62feaec48 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp @@ -245,6 +245,8 @@ void LandscapeEditorWindow::deleteSelectedLand() if (m_ui.landscapesListWidget->count() == 1) m_ui.deleteLandAction->setEnabled(false); + + m_undoStack->clear(); } int LandscapeEditorWindow::createLandscape(const QString &fileName) From 6d126906416975dc97f5d9a927b5c2e3f6c02f7b Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Mon, 18 Jul 2011 14:25:16 +0300 Subject: [PATCH 25/89] Changed: #1301 Added the add transition method. --HG-- branch : gsoc2011-worldeditorqt --- .../plugins/landscape_editor/builder_zone.cpp | 79 +++++++++++++++++++ .../plugins/landscape_editor/builder_zone.h | 2 +- 2 files changed, 80 insertions(+), 1 deletion(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp index cb97c20ea..62ed76e89 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp @@ -151,8 +151,87 @@ void ZoneBuilder::addZone(sint32 posX, sint32 posY) 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) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h index 213ba9b13..789af03f7 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h @@ -97,7 +97,7 @@ public: /// Zone Bricks /// @{ - void addZone(sint32 posX, sint32 posY); + void addZone(const sint32 posX, const sint32 posY); void addTransition(const sint32 posX, const sint32 posY); void delZone(const sint32 posX, const sint32 posY); /// @} From 4832fc6a373c6bbf484f144503d8cac8d321be8c Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Mon, 18 Jul 2011 14:26:06 +0300 Subject: [PATCH 26/89] Changed: #1301 Added new icons. --HG-- branch : gsoc2011-worldeditorqt --- .../plugins/landscape_editor/icons/ic_grid.png | Bin 0 -> 4204 bytes .../icons/ic_nel_transition_land.png | Bin 0 -> 55628 bytes .../landscape_editor/icons/ic_nel_zones.png | Bin 0 -> 30995 bytes .../landscape_editor/icons/ic_snapshot.png | Bin 0 -> 5390 bytes .../landscape_editor/landscape_editor.qrc | 4 ++++ .../landscape_editor_constants.h | 2 ++ 6 files changed, 6 insertions(+) create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/icons/ic_grid.png create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/icons/ic_nel_transition_land.png create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/icons/ic_nel_zones.png create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/icons/ic_snapshot.png diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/icons/ic_grid.png b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/icons/ic_grid.png new file mode 100644 index 0000000000000000000000000000000000000000..3534b70aece091d0f41a4adaed4aaf35e3b7fc5a GIT binary patch literal 4204 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 literal 0 HcmV?d00001 diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/icons/ic_nel_transition_land.png b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/icons/ic_nel_transition_land.png new file mode 100644 index 0000000000000000000000000000000000000000..99da545b1d20535d43518ce0672fee91fbc9f3ba GIT binary patch literal 55628 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

0k0EVh(yuUyJ*q`LaY5miEPIb z0>$(SE^e*x3epA~ZK^S0ODn-`5@j8kgN{rst+@j+5KG#ia~Tx1Cfv2YLXi8>(eGs{ z@v(%MKusOepKBgW_6=W>NvikTRKZ$#8(i6OzqCclY^8h?N&WHpd2u^R4t>=Wzc};oz!M@DwNrwtl&FBv z)NFs&AQ=t^&GK(S9j@fqW`S*0s^x>^m6clSjthqEnWyW#$@;E@P*jI^@p9$#m!RpV zOSt8MMAle{57GQMVPyK+ZXSZP#vw!BM`kOG00o6W=N#nyR=Sy~-jR_kNxJ;Jn5f)3 z+3Bveq>!awz8y@q|@r6_Hg*{svpW;t<2+s$yTO@#UWw{te;eQ%c+9d||b$JAV@?hBbv-l{| zV{mJz`_iW^ET4i)&Yg=aTmxPQn@FQ{rXR`Vfa-pes1!O-C~-zcX6K z7cd1mRpSmueJPcPPWHO?7Ch$iPK-KmH|biKN6!^_`MSfoFFj?Bj!DN2 zzWF%+rpjNX|M^%-$J-8N(XFes7frQImT?|CALeKLx87< z2*M{s2Pa78FA7vz%ALJ@zxEWQZ3d>0z8i$hc2%O}roJ(=MugeYJ><`M+b z_Codj?KkhL?er;oH>UF&5`zxUQ)i6r<+~)ndDlqRQIlH*P5VCLg>>q7(hvr2owH>wW(~?YTJC%07Lde(f|5LIaI2gu;k)BFsUFb3-Iw z6f*xMf=+)Qtv3RfK8axpQ(yACFavk_szupWj@D&<&mYbIUSSGzuWKR82a_Z|0&On! z=UB{Bo}M#@&%`jkh*cv+(-X3LnLJBXMK($4YVRUk47+U#?>RT9bxz1Go$Am4BtPrR zR%BB`fb2>C#1Sb~Iv@z&x_sfSUTLuHI;3kc`?$7$o{=}p-#^*5GqBrNm+B*SAYM5& z^h3+R3}k6?p1Al5$-Bw~)}!QWR5VH1Q-eSh;s@F9+>dB}%!hN0AJmo}rVB1xn#Oci z&#F!&6gXi)CGR>Qt?=BpflWnNDU55lIB*$tC@HVl0njD)5Q(e$so961)gjDskhs)K zhkadc$d(=wHv&5e@(@~}gzs>H4?LZQ_E!&QbZ8gmhrU#9-U!f3XTd=q;VBR5pg#tp z6%VPPUya-{^WK6wI-!J*4|``tfa>j|0L17d4$1 zJ-=!qmi(6Xp7u^N{1%|DK->8{7}LPZB09r6T#M0UHXAiwG_Q}*(R z51x)kMs)Fa7N2(BN`3TBLNw1afq4!`92|mZSj=lmOa2g*8HW)|?teiK)UFdc_U{uGfD@V)jaW_vq@7r|Ze=Ud>Gk#-j zq#aGfr>^Kej{D|kn+L{c$iHN~P68}?6@YwxgKM!=OW*%#g<{fD$jgrclyl@r;;@+i(Y0ercn8b>TGI8Hux_7wBVtHaF+f zn=yuEV{hICP9+jIzQHfE`=4eokzWP}OaHcVV!{#=`S1%$!dGSY&uIx#68GensOC+-38j=UuPYm#8 zIJCN{)S-Imxq>=Uz7Cyr4;e|)b|U`2nP6?RPQKy-@qp@>y$C_U-=$FGT z7lJoXQ``a18Pu<2BK?dq(7si%N~THW%3D!cC*bNiAxIqHV$ARaQgsx3trA4^?~w9O zz9%^`p*5XE*7NYF+Xg_a%<1?{rJkXHLycvk!`r)^KNjN+kf99wcy|p1EB(ZnyGE$s zwp3E604s2c9gKNypNb)2vpc+dwD_4_zo1b%8vP0zIvhOdopHKu`TWww|NUNcLU_m= z|6WTMQc>Ds=R>qMlNR;%pv$zyvxvNE<1EWImIpF~Cb?e^npV47}y>&q*JG z2!lq2%Q~r>KZtX6W9?B1y!ob-wD3eyu4R9jDt?C=>PE})z{}rS@$LjUlI300Jz!gU zlfuW%bUzwgfL_#uB zXCzPI?yT#7P1iU2Wro{5QyvHo&g6vwVqEjA7BgJZB6=Ad`YWc#)2JsnVgg%;+3yZg zcX#A=`}DqopJHyu$;K1F(1QtIu{GAQcOG2914^RkTN&sW=zKPj{^TYy^8l^&-k;^J zUt-C(XFCGhMVk$ap+@UOr*)US(4hnNxfv3w^+(QnvnL@A)@dQRdA(Aw-m9-Kw@;!0 z|CJN<#}D!hF<;q_s+gRjQyYL&P9dCl+ll6tw?K!k$N(36m?!sX`e}_Ex@q2X7tis& zp_mrH7nn6`V1JTseqwD(?zGNs#0(UU!LeX|vwi#4i;Vb-B_P*HUjY^oxsd$40=5pvgLUw~ zmA5|=9i;%$5KG~Fe*^Hj#P^8GV*-iUA1!+aOBzBadg!!CO zHmWCZ_jISa0wt#~u+`UgT^yz>0h{!s!(?$qJMt__eCJFcIs&{Q|=K~KVQnq&PoH+$f7H^?e>gW$gz^5(npG@m!}rXR`Shs#U2fQ zHiK){FO`bq8?WZ-`ml3zJ8Ke56D3NDI#yx_+l9btMh*nm()#w(8=<2dpZT-g{*6<) ziha&*r=7u_O0A;pVXmq#rZm4j(Bneie_}19J}-uHo^{SEx^MJIzx(a>;VJn!{y#~0 z@WA&p&;T?OUEWGUC30`9>agJ%<&D#-*T+fw(OLno{Tv*UzsJez1w+GS9xCI7EMKddKoPc{-vL+&*{c)nQFc4iyOrm zqkrQ+ckT^xGneQ2KKO8toL1bo#B`H$vDQ}3*OJg5TKUfT`{HJM zh(PRTXz)P`*Z3%d3R8aziU5OpPx0d}I7C|yI&eA_w{?|2Zjrm!cIO}qn}Dl5S@9oy znM4Rcy_4bn4$s2*)p&I&D|+6YGrRoF0B%8i+O{oxy)i{gmqx8^d(!@4A8)#EkfH$bT`+L%xk>fP^9#zcJ#k`?8e=Kf%0tIWYdi=F z{jE~`#=~M}hUE2c>G`}(0}agk6aE9}xqog}l-+{eAzt^Rd+C(s^u$GZ3S4VbDQXO6 z6Cbo`!p2@YKT%4}-vU%+Db`Dzx8~T_Bad~T@@Av!MxSj^?T$u8Q z=6;`RKX!a@EZ$XD9u51e+`|M<5VdQ59%{$fZBxWDI~w_BVo`-pXE zqiXd)w+`c(eh*;GxtsI%XSWeI?S;Png9yN*SHVJ#Zs&{56U&ppQ!njyH$exi5$U(NIYe`$(wy?o82SAlKN*uw9=dLc9I zZ`)j8N@fdB@H`}3IA#rtJtMk9H)2+Tw&(4w#g5J;a(=4@UuNDSzq>HW0;f5+a>+k0 zY`&SgI>-pzm;FW{L#Pq*GhR`Ub>``qhUtrXUQp%ZRfwd#zvzuLj!au#2k~Q(kwU4c zz|_QmpxEmudj9<%84rB+4!s&*xx9T9*W9lQ{D-g6cD?u_p!|0`;)Z(edxgf2K-5RGhJ7;uTp1PpK2?!^Mvv3!V`x1p=kOWh&zTXuOVyCcIE5!ddu zM{O}F!5{YKA*Xrr4>WivOTRLv*~`5)CrB=nA_v;k&k=k4DGSC{e$IIk8~aVxoqa8` zi=On0Q+xIN)BSyICcUo%?Q8x#;XUiaK4`b24a*=C*K}My0&&@NHY{4=gb+vN;8K)KY@hCQ1>KQ6oSql_^kEuHAepNPSc^lz%o7)AX-cq zOS*Mw-Di>DR`!%&BRAsRw>t})5r4H>l6WM7UuI&f|7NGutbZe66};VK5r(eQ2KYGu zS|#kypnu&&tw#3-dzMEw%*67JZ$|~_t+P)IKlx2n5h)#G=K4gV{HN*LooV%U54y{_ zxkJOl^95jD$ag0-;DGl#1$d~u^lOo1*sAVv#+Lgj-2e znC|sP2@QaD6h_+MJ7OYRx-itr(VJ3=vLM~v#1?HaQBWTf(gO|%lVrxPxcVj%4kdVO z+S*3rsBzHs<-|a#i^dJ-+hzbE81GDfk)J()L`#9}ss zQShA+&1awMJ1a^r9}pi9Kq0czo;eb`$W2M^wmVr_`?E}>7t>~2v^i#ExU~H^QI7mg zd&mC%sqbbPTAf|X7fumOaFeB@S&JgplDp(re_Pz<&m z<)Dy8X-bGP`)Ay%d(?h2pJIZn@x2xDwE^gS2QKgVcLPDJcCE2xFp8v(JNZnTqgYpE zE-f>)k59le#8Vl*-nODHL@rKlkw!C8cD^84+}#FFnNFnCTXo5a1O*@gT?{E9dfD&% zX`e9T6~m76 z^=A{B?r~H4lh9zDXznht`wHH*%bD`W9@wU_#+Gr6lz z+LA~s3<48fwDmjwjI; z|0U;7%VP5J@&(oI&-$5_Mdn>DVC#w=#OM<`ziqI;j%?pYC7y|I&K&x7lfi5J*=4GQ z3uwJcK$HOn55DI}y?8yY3;Y_6(ztq_!YwI@;;IeMo2mzFwM(cpcdgO~q z9WNPrGLXrw4uwPi=k*(}Oe~A4f?vx0@NKSPe{XZ6X6i-Pa8T;QAMv?Wp-Qh?l=ex* zQ>lwMRV5XZSWa_JoPqOh3=dcvyu9+SE^DxbCyzT4ja|UTy7tb!ECSzB60MY_2T*rn zl|&40Ctu%8Cwf-rE^c>qAh_G$@)~tN@&p|aSeAI57T12kz9YgAcaK%CQ(?H_szYGI zlEE9{@$koNHWn-g&9}a2E`;pcya#;FdmPwrIsVP5bqes$n)rI6OhEEzI{eCCq*kFB zE+mz365+QB#Qr?*!3sFfzwGjvglJhQW~?UunC zhZX9IYNwpjRNX8QB)tsp9_-76BB$oor=P~5I)V4`p*Ljjex(Z>n3!Z5DczU=y9QnT zdK;|{K%zb3C6>wzq7E+p37!dGRKAv(6&hdkhA{oe5RxcLl0FHX{9*3}8LR?$P}Og-hl zw(P{98Ie1*zL<-6Fz5pbF1pwE?Nwe~t77~L_0eO^z`IHoTJO_Ny0;`xwZS+Z8NvfP zWBdODB^e?uQ@<7=;9&WXQ}t2(k2K$%(vt0I^xmLKIO)JtVOuoB;;wq?~}zi7~;$%{Hqv4;7@N-;X{q zt}@^M@m;-oKWFF4y|mphoZ%Geb;M{dKgfS#Emz_zZt>f1%C`wV2TIpBD4TYJf7O4J zuru#^fksW!+e5ji;2+ z0uMdL6l91#RDUN+_8McL6jo&nMto z-{_$3&ApT_%wMh}UR?j!e$ncBn;v#m@2~OZHl8Nm;aJI=XHLB%N+!wlVF+W^9XYN8 z$KRTrw?eH?rmNXTp3#hSN(H^()-(O7s#Y_;^kq7|Ld<)bndy3yS8OqMp6Gno@8z7y z*8^5l>%K(sckSiV1Cxst?dY=~&HFEB1=6kxI88R?Uk%ia^b7HSWifvhuAB1fRkmk@ z<*!T0Q@;rIcbk=7hfrng$4&l zMMG;<)(SUNFN75ltocKkqNz7EO} zjZ)$vlzMWf^1bJN^86vJLp2WE>YepZ2+gnEeVIyqfxN_%Bf1{-5gl#&%iNIag$U0v zhnqV2(L@0aw7F?B{;o+9P*?+sZ7z`SK8n4MGsnE~7d3!#`wo3UKRxY@S59pMIQ$}S zUOH&cKtrz{F~2wu_yP}31x4SbzNWemP`(MUqiS$3FhP=vr5R(qUD~>Cxg&Ind&9=c zekmq9o(hP?HLTqA*RvCKiunGCBC>qLv^J+x{+0RBh@Lu?zbdBruu$}kS3 z0)VhwIvWfJ;y#as;Qy)$Z0N?L+EFUVCU?&?0U^}LUD&Jtn}t?~UuKdYgzjoD#&jPx z=6rb>y$^&ub9;A~?((O6s48hRx8-^2BB36=Hvmer;BK;Fn}@V!%}|fUxd!6P&fB*X zyoBxK+%y93%o8Nv^!dZfsf!K$^oomS_*95musyfasVVR6vX7S&dJkE_I0@)#hJRwB z@Jhy0gK$~yNA^L_5pg0}QdAs(qXiOE6l+gMPlsRxo7K46rkol`AR;UK>e(C09T&b<~IFxbmHYe z=+RQ%B~Nm*$x(!@bme*q$~*-IJIOlUl}?0^1%~{C!{po?FK4HmwC|mkSa03GU_HM$ zHGW6NpDU^J{tIQA&C7G!hk=%?q?(^-qVcB#gZTQ zMIFl&8mZL^Km#t)s-T(SRn{Kn(hbtyWkzjvG$N< zqhH%*2%9zQ&HUJ7|GH6Kyn@+lAo=Nj>0VArNr8Y&LdVQnJ#nTDb7xvYCjU{@m0#wq zRhdZ?*>}d6NR&GADevm6-RaZr@`|aI)23%z6p;KvMS6e~t%o;WpLi~GY+aps2hkK+ zj*J(6ZqETwU8?=CX&|O!GpM@Gb>Ff--&ZBSjBqqg>e*ZCS9D-Q?xU5Wo6Fi88-tzy zw~ntD$gfC^P2cm~RejUlOuw4*oGIz0$@mSUAHFQwODVG_rk~fJke>&R@7EB%mDnJM zhv*=C>oon-{b9>U3_2S^L*1^kSc=1DAj1 z%i>tu5{FJ-KOx!E-Z5U!4^`&=7Rg;rJj`>hj*L~loME;*U)5^Lpv~rJHO-4y$Qaqk zLNt>w=fC&LL1?IqUd8Z**R-IQ&Wr?`Ek?rax6GFw`B^+5aXD(Ip~1B7j>0_Sb-SC=(s zuPc~Gm6UPRljbfg_ka7lcKexSZL3l^pygQtE5_qvk)s)&fj?*q9(Z+3wYWmW{}B#WPi>s*LD%Jg46zR*WyH z&O5#gyvu@)h?~IKUWKdTSus`eId*I7j7*>%6qKXFxPrn62yb)waYRcA=8!SZ8KYjEEK>eI`n0PF$F51FGSTv%%_v14bcJCbTVLMtZ;?>P z!~n&NZKauKQwULIwXjZt%p#EXTCl@?L(K@8?%k#$e7G>i6P%I=Jq2J}`3A z(Oi>;uzcMS{(dtI&d!kYA#}k}@n(95WDC!*beJwvk7@l`)1h8oia-G2m$kYl+9)=d z-BT)85JNizvD#Yh^`1*5wSUUBa?@pUv#;1SWpB`h9yR4ybqo0f2sMZVB=VJs1i+ER z9AQyi(B!p=C*-f#ci1(4R5W$#!F6`CV54kjHL1oT$#)ym|JmZNBxNmcQ=J#b29vm6 z6OeYrs*;-LW||XgXS~$HcL!~lF5VQh8lJFcAtp|19L>y3$ia*d9Np#BO_IZGL*aZ< z7Nts2IAjezzp1P z9>!x1XWe`hUPD?>Ee^$G_vR_o%j$uOT|YqE{1RlzoKmZLBOShN9i983m_fmo=g&+O z8k^iK-@8w)JWOzoc(0lF?}Cd7Dk?zaio2nXb8rsJhG|pu@eMmyDpKGa7q(k0}rzwQz4$$gVQVgy$~(O6(vB+UDlIf3M?eqc1nae>g2u1YhaEyT1u1iSJ+R?|viPD$jLSf@#euqXE z_t|ycrKDB#MKqTeC za!o#A`mm>T<-dA!uX}W1JkY+-1BT5TlLTIHls-cYBJ(c9YC{CdA+%s2Lp`Yr{!T{w z&u9K%_fj_uP$vX3`d$o+VlJp*d3HuHQ+A5g90V!A65fA#T>C4bH#yLxp+9XK^f%a$A+SjYXajGLwSh-L>TinH% zJ22-7X$e6G#uZr3l^JINf3G0)_QxCcns#R^X9eaS@I4s&(wQX$a2m8-kF`&|SE**5 zz&bVbyy>THU6BU)T&Z#xnIWX_&%eS49@*l@v&p~?r>Jg!&-rrMO7w>w+}W9elgePr zo3`t@;_D)-S;P%`l5~h@&@20Z(72266U84tEj?*q{(W^?9Xe>|_dq&P`uECIiu7kD za6}8fF`M-tzsvFg6dZPk-QbUTtxn3{$ z2^SvS1EHQsFCQ>vjZ9aB(rc2T^rzRxIn%(IRj%* zJjr+uk?wm_b7#V1<93WIN^Ylo{@?VYG_=6TMvcL{EkY8HmbMd@{ zcIZ~OR_XQi^U2nF$`(9~>+-xb^IH5O$ST^h?40OScW3+kgV#BRR91a0Q}2P~_KOjL zAJbV7%)x#?CAe$NEbo6hmk(kE{zL*K`nr`CY{it&&uLUe$|?x`FdqTG&>L}z(4JoU z%N+jE_DePM!#=xaIKp6Aq;gD&CJ(Z$iO`Xz5kY6-cs{i_F?gUzT2|lb%ounc-awb|+v?Xg22tR-vgSfQa`)(k0ZW;MbU+D^ zB?cm7Lqas)-q&;9lkbP=m`>OB#5a^@-6%OAFi}()Rp8tP&zlp8^6+rA$rA%kzKh5HFj(m&-f=@ zG0n|_I7QOtfOL!8PssXLXDH|bEw>mM64vMyP^racp}s_vX~iF~HXuJLYW(u1b>akd zaQM9QsYU&^Od3Be$LR@brrfSgk}^0X==cJmxwXdf;MBG(S&fB^b~Vl+|Cj)Ju*dvM zCjhD=aWkKQAMw=JF=5d6giBAl@NJEzw;J&GZ4?Wo?_dfO<_W=}Raw1TZAx zKnhKg{>lj8J^3=wk7Bs?s$l)!IziPppy)WOa0~i9cH}inntR-5$%~a7*OB(>EfCbM@iqwTxO)H+CL@p))3v8S;V6UH9 zPaq*Wh;NVBv~O^LgB=aQ<~>1;B~jIuL7}{->flf?2K}_$q}lMq=Hqrj3ayp&5RD+H zk>Y#EkB%4XvTB68BTg^1F8QbDDQ_T~dYmWzYz7zcbU8 z?K;WwJ1x;YWrsm>&wOCzyvddxZtX9%v}dwzQ-3j$D=hF^z7<`%k8}&Y%df{|F70$P zGKGT$_+`Zeg?+>@$Tb3{c5=S zzYQ-k!Rg%$nz1;*%t`9?;0V`XPuZ>q4(6B_UT`6;B2 z`n%M@9II;!tz`Ku&)eR(;Jl|x`)ANOxwFvMyu}gy1-@}b!xBdYuKt#L>zEsivW1pU zlVHHAd$%swYUbN0@;O))tQR(~1X$o!t~f<)+tq=>p?6q{*!#)z&PSd}i%Z+7JMU+9 z)FA{vk>9eRoC{U9Ror7<(oOvOm4C^7i#tNL4C4vyzNK9=oh;uj7%zOTF2p&AXn)p- zK7oin0qcPu5`LrDU@!s?={P6v0rwP>ce>xSYTgp*uVbE)^Z03$We#JpWxbq6x zd2IK;(GM-!$GRv<2VWVvR5kFdX-r8ld7I;{snf7 zWn(SJb>nF3Xk{*?H$zPY-ekMei1gbb|0kKy|H85p|CL-c2smZUxplCf;-9D_(zQys zU8cU(N2BavhqR=_Uz5bezjq|p%eM6m=Q2h#+BVIeD(o0Moy)n&>v>=EnUBS<^OA;E zDVJ&IY8xYQCb9U8O^qIsfl#eU)ypB13kCnmtez-K09wf@EN=+o%U6M*X&LXC0d?Gf@@>%So|XNO z{ABIORSCu0I^d%EfB$f7Z_8~HBnm%<+=Sbud6bMK%DcW{F}}vE5*!9QU{_C$HAwyB zgso1lU+N`T)xEJL6{~OROOiK0?e^#>vqkzCU9gOoMrR-CGo;g@$rx2T&WS(HPE{R2xgi<7`$# z9q%sF^OX)zvLuJ(-zKtFrZH@9|GyO%FL`6z;Zm2!zJszEWAbixANxk4rHmVPO#<#!vY{Q6{l?;0;vHDE zf%2+X{(mvFCC_y$UAsN*lsng7fHuErZrqKC4SmhP$+U|vB)c(jsjS}T{XzqD+ONTA z`uhOS!6*=e_X&2CQh(QKytVhDUWK&oR%R--y3%nV-;SFgC^rcRFbmqUDQ0cF348W0 zMLBFn8@jqOx~!uyb2%c3kCM5`Cn?$RYJsJm`M&27c`Po%~pq@eZfA))J?MA9x%uy&fOeEJ24E z?}Gu#NKCqA=QUUO-xrUUbivE}cX}xZ7NTzq_gq;iP*<7oMjVt4!BodHfM_N(?tBmM z@(sE#uQ81ditD{SGQeN!;k!0kZ7N?w1(Rg)eF$~>oc>n5YU;puQW(4AAAUG)C6xr{ zNsu^|!1a$?{s$624fB-hES~;71)mjgrG*V28xxTsd%ZR~jbS1RzfG*|E##iUKSHEi zh#HYZ8>WIo7p=8hSCd_0aPJ&o5Cs}!uU9An<77G_Ly9RxNff9DPw&6QkQ1kCR{kKz z-=U2Kqse8@7th;D>gQOYO56L{H7n*c81q^uv$IcYp4Wtz;!yI5)GZju4ZNWWw8X=a zR(ow`^e|q?hRH$aVW+U5hMpBQj!DqMgjNUnbqy$)=aZE_`kj;^G63&~dj3V}^A z4k(fcMi$(IFokN-iX|d>tEu0LAL-C~4vB*rZ>3upEI}w(qCzi`#PVIst{7RCfXgiF zi4M^#@xwb+^6yl5iBncc(^HZgRyJG{vKo$HI!oml^(ITQwuuHI!16gSPjYs@MP%ANqgI^jQ6E=Lr zrd$bx;s`mev-4^rqy3~8(KQ*t=%~H;V&kamP}kJZjO0_*uNXj$rr;Uds1c|HhyoAh zKi9GKgYi>7k(`l^I5?Oz8?vlNX{Dx4Fz6dW^hwn#JbYo`gDSbeq(uDGD?ZFLq{fUa zKP>C}(Gmp&_k?8NVv#2E5j5Yyj233`-&NPI-B-c8)cUiCK2Y&Lb}d09p`tA5u9k4u z>1qszbwSQsjtHNS&;Sf%9|1#J(fA#=*FU_z&S~c6-oTfVSuImp8{rJ%VnEyRFg^Ix&>GUV?~@}Ha(s~=y*zqd5fl?@$rbC79o zl8kfwxTFvqH!Qrx>YO0_xJh@2S~x4%JhZ+p}tXS+mDfbA*Y#C!@Vsf^s00>j=7=$Nbr5 zOKnaj8Ft-qQLo` z#xFgjUBscV{;wn2uqd!s%$dY)|Kofp1(*vgkT2Kc=GI!CWT^cgJIN_|&Zd&Z*E}gG z;Z0}#|6}Pa{G#f=u6-tmLAsvAON$qUu53P1 zWC?+SrYKvcF!M^t!lD{H(VC@8VIpN+N8=^wGf-MsN}H?{u%2sr$+6_#Sog_yy__=R zU0X=sWHuSlORiv@@# zhzKD9mPBsg1?$!HrHD;0^#oc$7$HNp|E>`fj?9th4wVbIqD9IiZn?sgeMfrxl|2l z@s?cV@X&>?YOOAq_5XO6*qbg;qV`J8=XA2#NziFfMvlIUmQt2B@Z z7DJs{k*t|f6IEEj3rHn(k122r+3q?KayOR_1`>}7*SR3Wk0SXghY6P0upg!oohjb; z!H0bHkkyh2kxeDsfU$-}8yu2tG}ePby=T^4H`fh| ziARUx=6ZY(<~^z@HfV8RBO5^C1~mvW^zv0@d9-U?wus*@^Jo1){1&GF=o+Fbo2szg z#Tp09%^3b*dAqJ6sibf1k&e`8nB}e|u4nIaAlbKwjQkM1J;-q{?JhMNf{jTbvQ4$F zRG||0`h=j8d5U-Sj!#rIiz)~4^l8vAcDduV=VLqaXYWfN6QZEvHg5?J7|P%(n;4eN zo1&|$B~^m{Op@1>FkxGAJ;V1N8xUx6xG_%Z!Q%m9*kw4%H)+tjRS{oxI642zHD@Kl z4XiG~@zD$0OI_JhFj>hb0t(TNX-GB}&IY5RuXo6BCzaSJcs3DC@Rr5{*bZ>#F=W7a zjtu}6wMc9YA|D!y#j|A~VyoW^Q3()`l$KDhpEi5SmRKU{|Aie0G-K=ppjuSe-KIn9 zbLp2D>y)ACf!uyyPRPFTJekX|63D5$`|b*f_VQW%M-P(NK9hGO-VlvFJ5Y-Qq?`R! zU>H)%<4xEtFj!6MXWKWTN?7>Kbmx=RZvh>itWj7%NvVU>Z(DxJciiFy@x|e$6t)Ne z!_!xa0FW`jy7Uu_=g>M&lL+{etey?(w(xvZERFyh4irztORr991kTMA z4H+!s#Xf}=wywQt(p~?hrBOP^24*^ru5Zgq zr&)d`C3?#k#B#|?H~50OD>!NrL8kSB7}sGb5)$LOA_+Vp(k_qR0^DY+9`8PF6*(1F$)s9*SWq$ zIu64FDk}Og;=+G>=Xzd{FSV&AQvMNXtdTt~gbsrRI()hecUB^T@T{+85>MJ2|Gz!y zlvI?pvh`58@1rT-YoCQ^LZthF5OL)N?DB_n9Z0@Ep7|RZylni^Zt$y^k>6E?)m~G{ z`Kf#FP~snWv(oi6YO+2BhQ6$D0X{=*LY9ya%$F$BZx%`aph`YSSTV%t*Vc+zsJ_|B z#qZDF3+C7V_B~B11aS^c9~0Y*$9|3TBoRmx4-kkd@slipze^1u*iu6C&@Q=KmJ7-6 z{V6N|oV{Bd|H%%?nAbz1oX9BIHq^0ThQ}0rVN!4P*X&0dAaGG$Qk?psrWz~Dy{$}z zI8FtX30s2~E*=c`B{UE{ko68@3b4RXbKrdhD{P5T1K^E}5ba<7anBIL%EvxDz(Q68 ziLnZ_r+cr&Btq0F#gs^@>H|@B?s@5Z0PvroAYX*IJuNq);)4|!y^-y33IUM8BQBV5 zH|V=kkgZf<%|&eer*&mZbhXphq)@SOnJ=G_8t8=3K(Ro>Qc(7h^_2tVKEp(gHzeYr znJT3tOe{SdHQ!f~G;h0C5$DH$^V(>i)}!)Y5)AYF!O~mexYH+VSmHG-T}|mpzo#U{ zXS?%j`K*i;t<1&f>%l6$;%#dr<$NeQ*l_As?Vz7%^?Ho{o6V=t0mPV6vDG>xnHUL~ zE1*URmy!@-k;5XZ{?m<8YQ27Tt?e9F|0@->;Z0+O{V!FBS)dRNl4x@7k31w}C9|2<{d+o59H7mSZ6~IKc=v?ec`y&3O{_F!AJ+cm{Z&-w1?$3ld|qvZ zht94VqUtH&)DLipKhXdh{hX}+d%>SQQt=e~G-}BsX_?}-coNDC)%OF=aNF>YwzCgn zF|RtKW*PjnIFf^xwDBK-*;JSI@ai;}o2)Wt&LB0KfN{rZ_YR`&K%`upEGz+(y+>pIKZ4h5{D z+^Yoxib@wi0bVSKCBh=nJOK~&s~(oC%Slw_=VBTw9+1w~wAtLZ>)LLCb}#VVJh4bLe{`_S( zE*l{9Z52TI?0JA`kZb_wji>~9&&+^5MsTPCfhM0B%YbXN%nH7a53XBnFc!Ae@G8ZA zlL6SoV*yYlfT3QJZK%y4f`F+u7Ss)C&>ka+3}67s_7(fKnkrP}pXmXT%uD3cl|GM% zXVH<=K5dtr79_6(@P5{Mpa#nlUYy>@ZEZIyTLfEJoNPCJQmvFjoPbWEhyoVT-WY$b zbUeCsQ;d?m4Hpc91Hu~hKUq;6IJ>KHfbp_vbm;z$NuTdpFr)QAg><_sU4bDa?8G)T zsr!UIcnMjlpo7m~{(!~8S%-rW6BygbMKE6fT_^j!$iC~&RXawt&E)tNT}M8nXGC5``RWD4A%6F=SJGr8_fpRbdt{7_ymAj+ z%-X4s^M+RnKvILG#~j54kU61RU^sgwqddi~C!g3$bQq(NWvdG`Mw(L*^lQDK=Pp+Y zqK^xtrAS7iLWXHcdwB)SZXQct?-Uhhw&Qpf4`{)scPS}T|y z@lq)sv(q9AQnFPV*LBZ-nI_Kjvn_6AN0@dgi&LUm<$Ey-34pNAbW|W_#16xNB%k`0 z``i2eKA1IeizF?N$RyHiN4W8*g zc@g^eOxQS}Nu4(zKfo5cWC*AN4SR9__wqJtesTLSUriG}yti>dcPiMucclnunO>ND zziBc_dM*O$Zg373AF-6#Cg-F5?g(F#lS#?FjiTlzf2W6s+=}Y^jEWLBjX%2>qqo0+ zAsEM4LEO8)50*eGLCn9ml9LNYs@)Gg#uNO#06rFAZ~zpEBHECJ}kRMg8m zBoRt-M%==L`E<$Z&T9~&AmkQ@-V;7|83S=K(}YK4Sb!9IMDVcoyVrZ@&01}E^}$~o zx2L)q(>IP(%8a_2yyj0dD1rZl@eo2}`qk(L$9#HcJ&r`YVupF}p&OWOm@;IERrf7i z&3jc(8GGR~_f6afae*RKQS-b^WztOU*7n{JHa^?RTs z?+>&>2gpA2LSlo6_W$%0cQ6+xh*LZtJpIi86OeX{*r~CtFBYJgsnfj`E1toPISG%I zb!hQp`Y^IDf5}o%q@UG#r%{OHomK$#>5F^3A5JqD%=iEkyyVOC#s75yk2vM_rKbMz z*vNTMqL5$nZFf?i;87LhSf63&u$LlnPZC5UOT{@DR`TB0Zan zTjz-yVMRHsm{l8#_onXkt>n-T?VEVl8hPaQF9xu#iwYmTo{ted789;CeAlh8IW}l3 zLZ-G`<&EFq59q+!=L^5$M-Dnd_Qk&I8oFOCu@-xy#K{7mC>_3h6D$1fY=B@DJ`4)1 zAlV8yQ@&3RZ^?Zj+qy}GrxRfTkHga(+zt|2KWl8bg9IEcbQO1~wbe$N;$vZwBla}I zy2osX?XU}o{Z~;oT_CZ{h8L6+XdF--fmQ(rpJrJ&H%PGms9EL(^gu2}B+bRO_Bhm= ze-<9{LX+hYCY_$k9w|5V#7cK*6ydaAPhon#OiAlr_ zl9e44@f|Zf(vyZrM3nO191he~PH5KpwP@Qe8uq#U5#VS#(wVibS}7^y;tMekGM%@M z!~ScieWXn#2Ue=v-lv^M1*`;!eIIK=RCG0z+;N}+5j6Bhr2Z1JP8ti^tr*YV1@!0Z z5B=3_wP=~)kGHk%sIeKp7-9kXOLfr#_%HeP^SmD9&z}C$061U=z=K%F13o|(ehH7B zJn<@MaRkrJf=6ytB@qfr=ST(4pqq%NcJ?o-ledl>GzcvBcSbTXiWL@(6}m7(gt#;Y z*#DT{@aTFHi4J_!DX8XiuT7$D7B1rRlTT$n!#vB&^?ej6$t9J;M@=()Xk{nDI%AP3 zm|h72Hrmi+4{5r~?sWN*_Llt)ILW(n?7ku(1rL(E!~YGR;V|LF8iDaBIrdJFVw*`hh(-aM#y;(4hp3D52-^ zCZYS6m=dC4|FHmH<}Ss6noTyWdN%N?ND9k|%~KsB7}#_rT^%#BN^`;R+8$+8jeN-M zI?Gke61Ddtf6(c7P4O)FSbBmOXEn19 zbGxyaE<^9C7)J9gohM{+gCAc?AnT}l^7m3OJ^LW!JZK?hf3*GwIrf|2X6=!EJ0qfj z0;@}$)6!0_=3J9}aGgwSOk7;RtF3kwpE^>igUAOo4d*_RW9P9&Y>@uJK;lgKtwVb9 zul`6pF*a5~FaLX+`3C?8HKdX#8-cxm+CWh>OF`Q!-@s3G_L+}!ooYDf=dDPI3!XnM zS~|a;i@|j|KMSgDz6g4FR7uK-w`1RSe0^8I|9)A03zB9ZcA!r4>T&ohb^1C^^7}Qk z40m$AHGCl_WPdd-LGQl22&tAuv&y`>+9_>|JaZ2mx;N`20J8W+k=SB7Z`;H_>6YYb z{pD?(BJTe6|Mt{qmY95VSWo_>kWDRjw_u?SYYA^ zzuo~v`1dstro1>}K0^ne@9e zAb3B$>w=!a*=wIly(W6O2jRwOrrGz>37dA8pHf2-24>4G{-EBd9*w&@L%Jvj4yeaX zEQb8~O9`FdXtb4!Tp|T`N8Z{#%wicS>X0Q;EK1xGP$>Gj1q%y5FC;P=4N(M)^}p5P zZHf>WJgYX0G;pzeZZJTl-m9XZFkf3JeDh3qaq}tzd?ZG%1sevYBlys23FD+WED$kX}FY1N@DH6kQpl)rkZwmE4p z@yqY^98!fiLG zW4OJT5_?t9*69~kqC-ec&tM!sJ4!*rw})!vqK8133DMD^e*NT^URDz2-AO|}{GI6l z+aLzk46D^BJ!shV2@7w5}vSl*`Wx(OP<6I6(WtqFt zjPEqIV5KcsVJK~ZatPepGKxntuU~^FbLKfoeJK%rm!`IRd}{H__1O`9Io(fMPCOGu zvgP!^7KfEqb5Vrb@?d8+w4t17m2=$ik=ZA`bRChkBe?0873)3>Wq`pf=JK-eU~KH{ zKqq&mTo$MP+hS#`bhUcrmtJP`XefKIhN8^j49d}kJL)>#3R(wNslnNZh zl<+7*pL(k&oR?J%y?jjJ_9zfYoxg?W%x9S66z?!)6!4}U&!1&}K#h`JOfZj6*X*To z<(ds_cVYDfz3``omHVr41h+2ltHPDGn>jIC9gox8e%r@hoG*_~D(_Z7~A=Y-(%uytfrXl!)R%GUPOt?dM zw-?FQh^k@Yw@---$^J&l4?a2TF_E?{*%_*G>wZD#Ji{1~z$1P=e7HLduiVeyTm9Oj zcwk*+Y<@+E;iKYES4)Y)lW%Wy)TAGr81KL`^=*Y|LiwUVyD(Jz>)$*hv6uYyLQ+~V z$tS)}#=pluF;-hz`(U*2_{IOlTpB*&E!~^{NO;YiXf(0y*`*G3gfD4B)u7y+b8*E` zwvGsr$85@Tn6xMr{>| z33C+hEgnwyhX1d(_hIL+yyZ*QaFuPYxTto47{wqY)RG*+-jgOwCoib*Y35&C?EaFD z5Mkg4enLyqBKwbcoV`Em(Fop)p(+8Bd&;%;o`%5#tS0o5GvE4iNc2N$V`?YMdm20v zb#58;*1VzXn))sDltp!TXwYl-Bh_%?OjDgEoPv-l`7W9?M}E3!Z8km?X^Hyii4ZAOu2rxQU8J9%my zyuZ|ZXj6P7zsTm3iSvhe91KY{6$O|ozEzauuW+0_@=lSd2`)`FFfzPLpFA~u(k?

plD(}^MdE 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 literal 0 HcmV?d00001 diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/icons/ic_snapshot.png b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/icons/ic_snapshot.png new file mode 100644 index 0000000000000000000000000000000000000000..a45143aa4ccb7497fbe2da7481837ed539bdaf5d GIT binary patch literal 5390 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 scypx;po=E|sPMm7G>{aLa + icons/ic_nel_zones.png + icons/ic_snapshot.png + icons/ic_grid.png + icons/ic_nel_transition_land.png icons/ic_nel_landscape_item.png icons/ic_nel_landscape_settings.png icons/ic_nel_world_editor.png diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_constants.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_constants.h index 9ab2dbfbc..0cdf6d3cd 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_constants.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_constants.h @@ -33,6 +33,8 @@ const char * const LANDSCAPE_USE_OPENGL = "LandscapeUseOpenGL"; //resources 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 From 676e46813745869a71292506e298afac1b2384b7 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Mon, 18 Jul 2011 14:30:24 +0300 Subject: [PATCH 27/89] Changed: #1301 Added transition mode. --HG-- branch : gsoc2011-worldeditorqt --- .../landscape_editor/landscape_scene.cpp | 171 +++++++++++++++--- .../landscape_editor/landscape_scene.h | 9 +- 2 files changed, 158 insertions(+), 22 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp index b2dc9dd5d..67485158d 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp @@ -37,12 +37,17 @@ static const int LAYER_EMPTY_ZONES = 3; static const int LAYER_BLACKOUT = 4; const char * const LAYER_BLACKOUT_NAME = "blackout"; -LandscapeScene::LandscapeScene(QObject *parent) +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) { - m_cellSize = 160; + setSceneRect(QRectF(0, m_cellSize, MAX_SCENE_WIDTH * m_cellSize, MAX_SCENE_HEIGHT * m_cellSize)); } LandscapeScene::~LandscapeScene() @@ -279,17 +284,18 @@ void LandscapeScene::snapshot(const QString &fileName, int width, int height, co QString LandscapeScene::zoneNameFromMousePos() const { - if ((m_posY > 0) || (m_posY < -255) || - (m_posX < 0) || (m_posX > 255)) + 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").arg(-m_posY).arg(QChar('A' + (m_posX/26))).arg(QChar('A' + (m_posX%26))); + 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().rx(); - qreal y = mouseEvent->scenePos().ry(); + qreal x = mouseEvent->scenePos().x(); + qreal y = mouseEvent->scenePos().y(); if ((x < 0) || (y < 0)) return; @@ -298,12 +304,20 @@ void LandscapeScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) if (m_zoneBuilder == 0) return; + if (m_transitionMode) + { + if (mouseEvent->button() == Qt::LeftButton) - 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); - + // 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); @@ -311,8 +325,8 @@ void LandscapeScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) void LandscapeScene::mouseMoveEvent(QGraphicsSceneMouseEvent * mouseEvent) { - qreal x = mouseEvent->scenePos().rx(); - qreal y = mouseEvent->scenePos().ry(); + qreal x = mouseEvent->scenePos().x(); + qreal y = mouseEvent->scenePos().y(); sint32 posX = sint32(floor(x / m_cellSize)); sint32 posY = sint32(-floor(y / m_cellSize)); @@ -321,11 +335,16 @@ void LandscapeScene::mouseMoveEvent(QGraphicsSceneMouseEvent * mouseEvent) (m_mouseButton == Qt::LeftButton || m_mouseButton == Qt::RightButton)) { - if (m_mouseButton == Qt::LeftButton) - m_zoneBuilder->addZone(posX, posY); - else if (m_mouseButton == Qt::RightButton) - m_zoneBuilder->delZone(posX, posY); - + 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(); @@ -334,8 +353,8 @@ void LandscapeScene::mouseMoveEvent(QGraphicsSceneMouseEvent * mouseEvent) m_posX = posX; m_posY = posY; - m_mouseX = mouseEvent->scenePos().rx(); - m_mouseY = mouseEvent->scenePos().ry(); + m_mouseX = mouseEvent->scenePos().x(); + m_mouseY = mouseEvent->scenePos().y() - m_cellSize; QGraphicsScene::mouseMoveEvent(mouseEvent); } @@ -357,9 +376,23 @@ bool LandscapeScene::checkUnderZone(const int posX, const int posY) 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)); @@ -381,4 +414,100 @@ void LandscapeScene::drawForeground(QPainter *painter, const QRectF &rect) */ } +void LandscapeScene::drawTransition(QPainter *painter, const QRectF &rect) +{ + int left = int(floor(rect.left() / m_cellSize)); + int right = int(floor(rect.right() / m_cellSize)); + int top = int(floor(rect.top() / m_cellSize)); + int bottom = int(floor(rect.bottom() / m_cellSize)); + + QVector redLines; + QVector 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 */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h index 71d4c512e..8a31ed15d 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h @@ -43,7 +43,7 @@ class LANDSCAPE_EDITOR_EXPORT LandscapeScene : public QGraphicsScene Q_OBJECT public: - LandscapeScene(QObject *parent = 0); + LandscapeScene(int sizeCell = 160, QObject *parent = 0); virtual ~LandscapeScene(); int cellSize() const; @@ -60,6 +60,10 @@ public: 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); @@ -67,10 +71,13 @@ protected: 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; From 2baa68b89c7a43e93f07671baddf6f291c8b2c09 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Mon, 18 Jul 2011 14:32:54 +0300 Subject: [PATCH 28/89] Changed: #1301 Improved appearance of landscape editor. --HG-- branch : gsoc2011-worldeditorqt --- .../landscape_editor_window.cpp | 22 +++++--- .../landscape_editor_window.ui | 52 ++++++++++++----- .../landscape_editor/landscape_view.cpp | 56 +++++++++++-------- .../plugins/landscape_editor/landscape_view.h | 2 + .../landscape_editor/shapshot_dialog.ui | 8 ++- 5 files changed, 93 insertions(+), 47 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp index 62feaec48..a97dcf380 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp @@ -56,7 +56,7 @@ LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent) m_ui.setupUi(this); m_undoStack = new QUndoStack(this); - m_landscapeScene = new LandscapeScene(this); + m_landscapeScene = new LandscapeScene(160, this); m_zoneBuilder = new ZoneBuilder(m_landscapeScene, m_ui.zoneListWidget, m_undoStack); m_ui.zoneListWidget->setZoneBuilder(m_zoneBuilder); @@ -69,6 +69,9 @@ LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent) 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(); @@ -85,6 +88,7 @@ LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent) 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); @@ -353,23 +357,27 @@ 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.undoToolBar->addAction(action); + m_ui.fileToolBar->addAction(action); action = menuManager->action(Core::Constants::REDO); if (action != 0) - m_ui.undoToolBar->addAction(action); + 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); + 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() diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui index b2db9dc42..77133c593 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.ui @@ -31,8 +31,8 @@ 0.000000000000000 0.000000000000000 - 99999.000000000000000 - 99999.000000000000000 + 0.000000000000000 + 0.000000000000000 @@ -65,7 +65,11 @@ false - + + + + :/icons/ic_nel_zones.png:/icons/ic_nel_zones.png + Zones @@ -74,18 +78,11 @@ - - - toolBar_2 - - - TopToolBarArea - - - false - - + + + :/icons/ic_nel_zone.png:/icons/ic_nel_zone.png + Landscapes @@ -116,9 +113,10 @@ false + + - @@ -136,6 +134,10 @@ true + + + :/icons/ic_grid.png:/icons/ic_grid.png + EnableGrid @@ -147,6 +149,10 @@ + + + :/icons/ic_snapshot.png:/icons/ic_snapshot.png + snapshot @@ -200,6 +206,22 @@ Create new landscape + + + true + + + + :/icons/ic_nel_landscape_item.png + :/icons/ic_nel_transition_land.png:/icons/ic_nel_landscape_item.png + + + Transition mode + + + Enable transition mode + + diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp index 40074292d..263417204 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp @@ -59,9 +59,7 @@ bool LandscapeView::isVisibleGrid() const void LandscapeView::setVisibleGrid(bool visible) { m_visibleGrid = visible; - - // hack for repaint view - translate(0.0001, 0.0001); + scene()->update(); } void LandscapeView::wheelEvent(QWheelEvent *event) @@ -117,45 +115,55 @@ void LandscapeView::drawForeground(QPainter *painter, const QRectF &rect) if (!m_visibleGrid) return; - qreal scaleFactor = transform().m11(); painter->setPen(QPen(Qt::white, 0, Qt::SolidLine)); + drawGrid(painter, rect); - // draw grid + 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); - // draw vertical lines + QVector lines; + + // Calculate vertical lines while (left < rect.right()) { - painter->drawLine(int(left), int(rect.bottom()), int(left), int(rect.top())); + lines.push_back(QLine(int(left), int(rect.bottom()), int(left), int(rect.top()))); left += m_cellSize; } - // draw horizontal lines + // Calculate horizontal lines while (top < rect.bottom()) { - painter->drawLine(int(rect.left()), int(top), int(rect.right()), int(top)); + lines.push_back(QLine(int(rect.left()), int(top), int(rect.right()), int(top))); top += m_cellSize; } - // Render text (slow!) - if (m_numSteps > -m_maxSteps / 4) - { - painter->setPen(QPen(Qt::white, 0.5, Qt::SolidLine)); + // Draw lines + painter->drawLines(lines); +} - //painter->setFont(QFont("Helvetica [Cronyx]", 12)); - 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)); +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 i = leftSide; i < rightSide + 1; ++i) + { + for (int j = topSide; j < bottomSide + 1; ++j) { - 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); - } + 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); } } } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h index 2ae251fee..0673db82c 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h @@ -49,6 +49,8 @@ protected: 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; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/shapshot_dialog.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/shapshot_dialog.ui index 1c25a2ace..66f657012 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/shapshot_dialog.ui +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/shapshot_dialog.ui @@ -13,6 +13,10 @@ Snapshot + + + :/icons/ic_snapshot.png:/icons/ic_snapshot.png + @@ -136,7 +140,9 @@ keepRatioCheckBox buttonBox - + + + buttonBox From 29f78e79feedf2377599b10a84223cd11ea17654 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Wed, 20 Jul 2011 18:07:46 +0300 Subject: [PATCH 29/89] Changed: #1302 Added initial database of primitives (model/view) (loading of *. primitive file) --HG-- branch : gsoc2011-worldeditorqt --- .../src/plugins/world_editor/CMakeLists.txt | 1 + .../plugins/world_editor/primitive_item.cpp | 145 +++++++++++++++ .../src/plugins/world_editor/primitive_item.h | 99 ++++++++++ .../plugins/world_editor/primitives_model.cpp | 172 ++++++++++++++++++ .../plugins/world_editor/primitives_model.h | 65 +++++++ .../world_editor/world_editor_actions.cpp | 47 +++++ .../world_editor/world_editor_actions.h | 48 +++++ .../world_editor/world_editor_constants.h | 4 + .../world_editor/world_editor_plugin.cpp | 34 +++- .../world_editor/world_editor_plugin.h | 2 + .../world_editor/world_editor_window.cpp | 58 ++++-- .../world_editor/world_editor_window.h | 4 + .../world_editor/world_editor_window.ui | 41 ++++- 13 files changed, 702 insertions(+), 18 deletions(-) create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.cpp create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.cpp create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.h create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/CMakeLists.txt index 784dd6139..c8b034444 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/CMakeLists.txt +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/CMakeLists.txt @@ -11,6 +11,7 @@ SET(OVQT_EXT_SYS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/../../extension_system/iplugin. SET(OVQT_PLUGIN_WORLD_EDITOR_HDR world_editor_plugin.h world_editor_window.h + primitives_model.h ) SET(OVQT_PLUGIN_WORLD_EDITOR_UIS world_editor_window.ui diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.cpp new file mode 100644 index 000000000..9ec95bdaa --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.cpp @@ -0,0 +1,145 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +// Project includes +#include "primitive_item.h" + +// Qt includes +#include + +namespace WorldEditor +{ + +BaseTreeItem::BaseTreeItem(BaseTreeItem *parent) +{ + m_parentItem = parent; + m_itemData << QIcon() << "" << "" << ""; +} + +BaseTreeItem::BaseTreeItem(const QList &data, BaseTreeItem *parent) +{ + m_parentItem = parent; + m_itemData = data; +} + +BaseTreeItem::~BaseTreeItem() +{ + qDeleteAll(m_childItems); +} + +void BaseTreeItem::appendChild(BaseTreeItem *item) +{ + m_childItems.append(item); +} + +BaseTreeItem *BaseTreeItem::child(int row) +{ + return m_childItems.value(row); +} + +int BaseTreeItem::childCount() const +{ + return m_childItems.count(); +} + +int BaseTreeItem::columnCount() const +{ + return m_itemData.count(); +} + +QVariant BaseTreeItem::data(int column) const +{ + return m_itemData.value(column); +} + +void BaseTreeItem::setData(int column, const QVariant &data) +{ + m_itemData[column] = data; +} + +BaseTreeItem *BaseTreeItem::parent() +{ + return m_parentItem; +} + +int BaseTreeItem::row() const +{ + if (m_parentItem) + return m_parentItem->m_childItems.indexOf(const_cast(this)); + + return 0; +} + +void BaseTreeItem::setModified(bool value) +{ + m_modified = value; +} + +bool BaseTreeItem::isModified() const +{ + return m_modified; +} + +PrimitiveItem::PrimitiveItem(NLLIGO::IPrimitive *primitive, BaseTreeItem *parent) + : BaseTreeItem(parent), + m_primitive(primitive) +{ + setData(1, QString(m_primitive->getName().c_str())); + setData(2, QString(m_primitive->getClassName().c_str())); + + std::string className; + m_primitive->getPropertyByName("class", className); + + // Set Icon + QIcon icon(QString("./old_ico/%1.ico").arg(className.c_str())); + if (primitive->getParent() == NULL) + icon = QIcon("./old_ico/root.ico"); + if (icon.isNull()) + { + if (primitive->getNumChildren() == 0) + icon = QIcon("./old_ico/property.ico"); + else + icon = QIcon("./old_ico/folder_h.ico"); + } + setData(0, icon); + + setData(3, QString(className.c_str())); +} +/* +PrimitiveItem::PrimitiveItem(const PrimitiveItem &other) +{ +} +*/ +PrimitiveItem::~PrimitiveItem() +{ +} + +PrimitivesItem::PrimitivesItem(const QString &name, NLLIGO::CPrimitives *primitives, BaseTreeItem *parent) + : PrimitiveItem(primitives->RootNode, parent), + m_primitives(primitives) +{ + setData(1, name); +} +/* +PrimitivesItem::PrimitivesItem(const PrimitiveItem &other) +{ +} +*/ +PrimitivesItem::~PrimitivesItem() +{ +} + +} /* namespace WorldEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h new file mode 100644 index 000000000..26ca70670 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h @@ -0,0 +1,99 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +#ifndef PRIMITIVE_ITEM_H +#define PRIMITIVE_ITEM_H + +// Project includes + +// NeL includes +#include + +// Qt includes +#include +#include +#include + +namespace WorldEditor +{ + +/* +@class BaseTreeItem +@brief +@details +*/ +class BaseTreeItem +{ +public: + BaseTreeItem(BaseTreeItem *parent = 0); + BaseTreeItem(const QList &data, BaseTreeItem *parent = 0); + virtual ~BaseTreeItem(); + + void appendChild(BaseTreeItem *child); + + BaseTreeItem *child(int row); + int childCount() const; + int columnCount() const; + QVariant data(int column) const; + void setData(int column, const QVariant &data); + int row() const; + BaseTreeItem *parent(); + void setModified(bool value); + bool isModified() const; + +private: + + bool m_modified; + QList m_childItems; + QList m_itemData; + BaseTreeItem *m_parentItem; +}; + +/* +@class PrimitiveItem +@brief +@details +*/ +class PrimitiveItem: public BaseTreeItem +{ +public: + PrimitiveItem(NLLIGO::IPrimitive *primitive, BaseTreeItem *parent); + PrimitiveItem(const PrimitiveItem &other); + virtual ~PrimitiveItem(); + +private: + NLLIGO::IPrimitive *m_primitive; +}; + +/* +@class PrimitivesItem +@brief +@details +*/ +class PrimitivesItem: public PrimitiveItem +{ +public: + PrimitivesItem(const QString &name, NLLIGO::CPrimitives *primitives, BaseTreeItem *parent); + PrimitivesItem(const PrimitiveItem &other); + virtual ~PrimitivesItem(); + +private: + NLLIGO::CPrimitives *m_primitives; +}; + +} /* namespace WorldEditor */ + +#endif // PRIMITIVE_ITEM_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.cpp new file mode 100644 index 000000000..8c5af6229 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.cpp @@ -0,0 +1,172 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +#include +#include +#include + +#include + +#include "primitive_item.h" +#include "primitives_model.h" + +namespace WorldEditor +{ + +PrimitivesTreeModel::PrimitivesTreeModel(QObject *parent) + : QAbstractItemModel(parent) +{ + QList rootData; + rootData << "Name" << "Class" << "Class"; + m_rootItem = new BaseTreeItem(rootData); +} + +PrimitivesTreeModel::~PrimitivesTreeModel() +{ + delete m_rootItem; +} + +int PrimitivesTreeModel::columnCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + return static_cast(parent.internalPointer())->columnCount(); + else + return m_rootItem->columnCount(); +} + +QVariant PrimitivesTreeModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + BaseTreeItem *item = static_cast(index.internalPointer()); + switch (role) + { +// case Qt::TextAlignmentRole: +// return int(Qt::AlignLeft | Qt::AlignVCenter); + case Qt::DisplayRole: + return item->data(index.column() + 1); + case Qt::DecorationRole: + { + if (index.column() == 0) + return qVariantFromValue(item->data(0)); + else + return QVariant(); + } + 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_rootItem->data(section); + + return QVariant(); +} + +QModelIndex PrimitivesTreeModel::index(int row, int column, const QModelIndex &parent) +const +{ + if (!hasIndex(row, column, parent)) + return QModelIndex(); + + BaseTreeItem *parentItem; + + if (!parent.isValid()) + parentItem = m_rootItem; + else + parentItem = static_cast(parent.internalPointer()); + + BaseTreeItem *childItem = parentItem->child(row); + if (childItem) + return createIndex(row, column, childItem); + else + return QModelIndex(); +} + +QModelIndex PrimitivesTreeModel::parent(const QModelIndex &index) const +{ + if (!index.isValid()) + return QModelIndex(); + + BaseTreeItem *childItem = static_cast(index.internalPointer()); + BaseTreeItem *parentItem = childItem->parent(); + + if (parentItem == m_rootItem) + return QModelIndex(); + + return createIndex(parentItem->row(), 0, parentItem); +} + +int PrimitivesTreeModel::rowCount(const QModelIndex &parent) const +{ + BaseTreeItem *parentItem; + if (parent.column() > 0) + return 0; + + if (!parent.isValid()) + parentItem = m_rootItem; + else + parentItem = static_cast(parent.internalPointer()); + + return parentItem->childCount(); +} + +void PrimitivesTreeModel::addPrimitives(const QString &name, NLLIGO::CPrimitives *primitives) +{ + beginResetModel(); + PrimitivesItem *newPrimitives = new PrimitivesItem(name, primitives, m_rootItem); + m_rootItem->appendChild(newPrimitives); + for (uint i = 0; i < primitives->RootNode->getNumChildren(); ++i) + { + NLLIGO::IPrimitive *childPrim; + primitives->RootNode->getChild(childPrim, i); + scanPrimitive(childPrim, newPrimitives); + } + endResetModel(); +} + +void PrimitivesTreeModel::scanPrimitive(NLLIGO::IPrimitive *prim, BaseTreeItem *parent) +{ +// const NLLIGO::CPrimitiveClass *primClass = NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig->getPrimitiveClass(*prim); +// nlassert (primClass); +// if (primClass->Type == NLLIGO::CPrimitiveClass::Alias) +// return; + if (prim->getClassName() == "CPrimAlias") + return; + + PrimitiveItem *newItem = new PrimitiveItem(prim, parent); + parent->appendChild(newItem); + for (uint i = 0; i < prim->getNumChildren(); ++i) + { + NLLIGO::IPrimitive *childPrim; + prim->getChild(childPrim, i); + scanPrimitive(childPrim, newItem); + } +} + +} /* namespace WorldEditor */ \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.h new file mode 100644 index 000000000..5098d1e5e --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.h @@ -0,0 +1,65 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + + +#ifndef PRIMITIVES_MODEL_H +#define PRIMITIVES_MODEL_H + +#include + +#include +#include +#include + +namespace WorldEditor +{ + +class BaseTreeItem; + +/** +@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; + + void addPrimitives(const QString &name, NLLIGO::CPrimitives *primitives); + +private: + void scanPrimitive(NLLIGO::IPrimitive *prim, BaseTreeItem *parent = 0); + + BaseTreeItem *m_rootItem; +}; + +} /* namespace WorldEditor */ + +#endif // PRIMITIVES_MODEL_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp new file mode 100644 index 000000000..cae402d27 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp @@ -0,0 +1,47 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +// Project includes +#include "world_editor_actions.h" + +// NeL includes +#include + +// Qt includes + +namespace WorldEditor +{ + +OpenLandscapeCommand::OpenLandscapeCommand(const QString &fileName, QUndoCommand *parent) + : QUndoCommand(parent), + m_fileName(fileName) +{ +} + +OpenLandscapeCommand::~OpenLandscapeCommand() +{ +} + +void OpenLandscapeCommand::undo() +{ +} + +void OpenLandscapeCommand::redo() +{ +} + +} /* namespace WorldEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h new file mode 100644 index 000000000..5a1c1ea49 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h @@ -0,0 +1,48 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +#ifndef WORLD_EDITOR_ACTIONS_H +#define WORLD_EDITOR_ACTIONS_H + +// Project includes + +// NeL includes + +// Qt includes +#include +#include +#include + +namespace WorldEditor +{ + +class OpenLandscapeCommand: public QUndoCommand +{ +public: + OpenLandscapeCommand(const QString &fileName, QUndoCommand *parent = 0); + virtual ~OpenLandscapeCommand(); + + virtual void undo(); + virtual void redo(); +private: + + QString m_fileName; +}; + +} /* namespace WorldEditor */ + +#endif // WORLD_EDITOR_ACTIONS_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_constants.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_constants.h index 644f79b53..a54b82cb1 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_constants.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_constants.h @@ -28,6 +28,10 @@ const char * const WORLD_EDITOR_PLUGIN = "WorldEditor"; 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"; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_plugin.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_plugin.cpp index 494f6e2b6..90d2de6d6 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_plugin.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_plugin.cpp @@ -24,6 +24,9 @@ // NeL includes #include "nel/misc/debug.h" +#include +#include +#include // Qt includes #include @@ -43,8 +46,35 @@ WorldEditorPlugin::~WorldEditorPlugin() bool WorldEditorPlugin::initialize(ExtensionSystem::IPluginManager *pluginManager, QString *errorString) { - Q_UNUSED(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; @@ -115,7 +145,7 @@ QUndoStack *WorldEditorContext::undoStack() void WorldEditorContext::open() { - //m_worldEditorWindow->open(); + m_worldEditorWindow->open(); } QWidget *WorldEditorContext::widget() diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_plugin.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_plugin.h index fdfff7eff..11e2c7871 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_plugin.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_plugin.h @@ -25,6 +25,7 @@ // NeL includes #include "nel/misc/app_context.h" +#include // Qt includes #include @@ -70,6 +71,7 @@ protected: NLMISC::CLibraryContext *m_libContext; private: + NLLIGO::CLigoConfig m_ligoConfig; ExtensionSystem::IPluginManager *m_plugMan; QList m_autoReleaseObjects; }; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp index 7d6f9dcfd..8d2c0c7f1 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp @@ -18,13 +18,25 @@ // Project includes #include "world_editor_window.h" #include "world_editor_constants.h" +#include "primitives_model.h" #include "../core/icore.h" #include "../core/imenu_manager.h" #include "../core/core_constants.h" +// NeL includes +#include +#include +#include + +#include +#include +#include +#include + // Qt includes #include +#include namespace WorldEditor { @@ -32,11 +44,15 @@ QString _lastDir; WorldEditorWindow::WorldEditorWindow(QWidget *parent) : QMainWindow(parent), + m_primitivesModel(0), m_undoStack(0) { m_ui.setupUi(this); m_undoStack = new QUndoStack(this); + m_primitivesModel = new PrimitivesTreeModel(); + m_ui.treePrimitivesView->setModel(m_primitivesModel); + createMenus(); createToolBars(); // readSettings(); @@ -54,20 +70,33 @@ QUndoStack *WorldEditorWindow::undoStack() const void WorldEditorWindow::open() { - /* QStringList fileNames = QFileDialog::getOpenFileNames(this, - tr("Open NeL Ligo land file"), _lastDir, - tr("All NeL Ligo land files (*.land)")); - - setCursor(Qt::WaitCursor); - if (!fileNames.isEmpty()) + QStringList fileNames = QFileDialog::getOpenFileNames(this, + tr("Open NeL Ligo primitive file"), _lastDir, + tr("All NeL Ligo primitive files (*.primitive)")); + + setCursor(Qt::WaitCursor); + if (!fileNames.isEmpty()) + { + QStringList list = fileNames; + _lastDir = QFileInfo(list.front()).absolutePath(); + Q_FOREACH(QString fileName, fileNames) { - QStringList list = fileNames; - _lastDir = QFileInfo(list.front()).absolutePath(); - Q_FOREACH(QString fileName, fileNames) - { - } + loadPrimitive(fileName); } - setCursor(Qt::ArrowCursor);*/ + } + setCursor(Qt::ArrowCursor); +} + +void WorldEditorWindow::loadPrimitive(const QString &fileName) +{ + NLLIGO::CPrimitives *primitives = new NLLIGO::CPrimitives(); + + // set the primitive context + NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = primitives; + + NLLIGO::loadXmlPrimitiveFile(*primitives, fileName.toStdString(), *NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig); + + m_primitivesModel->addPrimitives(fileName, primitives); } void WorldEditorWindow::createMenus() @@ -82,14 +111,15 @@ void WorldEditorWindow::createToolBars() //m_ui.fileToolBar->addAction(action); QAction *action = menuManager->action(Core::Constants::OPEN); m_ui.fileToolBar->addAction(action); + m_ui.fileToolBar->addSeparator(); action = menuManager->action(Core::Constants::UNDO); if (action != 0) - m_ui.undoToolBar->addAction(action); + m_ui.fileToolBar->addAction(action); action = menuManager->action(Core::Constants::REDO); if (action != 0) - m_ui.undoToolBar->addAction(action); + m_ui.fileToolBar->addAction(action); //action = menuManager->action(Core::Constants::SAVE); //m_ui.fileToolBar->addAction(action); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h index 8efafc48b..8311ffcc6 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h @@ -26,6 +26,7 @@ namespace WorldEditor { +class PrimitivesTreeModel; class WorldEditorWindow: public QMainWindow { @@ -48,6 +49,9 @@ private: void readSettings(); void writeSettings(); + void loadPrimitive(const QString &fileName); + + PrimitivesTreeModel *m_primitivesModel; QUndoStack *m_undoStack; Ui::WorldEditorWindow m_ui; }; /* class WorldEditorWindow */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui index 86c8a2b11..6f597ca2a 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui @@ -20,7 +20,7 @@ - + @@ -35,7 +35,7 @@ false - + toolBar @@ -45,8 +45,45 @@ false + + + + + 2 + + + + + 3 + + + 3 + + + + + + + + + + loadPrimitive + + + + + newPrimitive + + + + + LandscapeEditor::LandscapeView + QGraphicsView +

../landscape_editor/landscape_view.h
+
+
From 0c1a463b975bdcb2d943341c2f77a2bdaa45b61a Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Wed, 27 Jul 2011 19:01:54 +0300 Subject: [PATCH 30/89] Changed: #1301 Added LandscapeSceneBase and ZoneBuilderBase classes for world editor plugin (ZoneBuilder and LandscapeScene classes are being divided on two separatly classes). --HG-- branch : gsoc2011-worldeditorqt --- .../plugins/landscape_editor/CMakeLists.txt | 1 + .../plugins/landscape_editor/builder_zone.h | 24 +- .../landscape_editor/builder_zone_base.cpp | 301 ++++++++++++++++ .../landscape_editor/builder_zone_base.h | 139 ++++++++ .../landscape_editor/landscape_scene.h | 2 +- .../landscape_editor/landscape_scene_base.cpp | 320 ++++++++++++++++++ .../landscape_editor/landscape_scene_base.h | 81 +++++ .../project_settings_dialog.h | 3 +- 8 files changed, 846 insertions(+), 25 deletions(-) create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_base.cpp create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_base.h create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene_base.cpp create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene_base.h diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt index 7ef0a11bf..4681c5d8b 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt @@ -11,6 +11,7 @@ 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 diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h index 789af03f7..d16008a5f 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h @@ -19,6 +19,7 @@ #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" @@ -46,29 +47,6 @@ class ListZonesWidget; class LandscapeScene; class UndoScanRegionCommand; -// 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. diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_base.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_base.cpp new file mode 100644 index 000000000..a8fc40cab --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_base.cpp @@ -0,0 +1,301 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +// Project includes +#include "builder_zone_base.h" +#include "list_zones_widget.h" +#include "landscape_actions.h" + +// NeL includes +#include + +// Qt includes +#include +#include +#include + +namespace LandscapeEditor +{ +int NewLandId = 0; + +ZoneBuilderBase::ZoneBuilderBase(LandscapeScene *landscapeScene) + : m_currentZoneRegion(-1), + m_pixmapDatabase(0), + m_landscapeScene(landscapeScene) +{ + nlassert(m_landscapeScene); + 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::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(NewLandId, landItem); + if (m_currentZoneRegion == -1) + setCurrentZoneRegion(NewLandId); + + calcMask(); + return NewLandId++; +} + +int ZoneBuilderBase::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(NewLandId, landItem); + + if (m_currentZoneRegion == -1) + setCurrentZoneRegion(NewLandId); + + calcMask(); + return NewLandId++; +} + +void ZoneBuilderBase::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 ZoneBuilderBase::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 ZoneBuilderBase::currentIdZoneRegion() const +{ + return m_currentZoneRegion; +} + +ZoneRegionObject *ZoneBuilderBase::currentZoneRegion() const +{ + return m_landscapeMap.value(m_currentZoneRegion).zoneRegionObject; +} + +int ZoneBuilderBase::countZoneRegion() const +{ + return m_landscapeMap.size(); +} + +ZoneRegionObject *ZoneBuilderBase::zoneRegion(int id) const +{ + return m_landscapeMap.value(id).zoneRegionObject; +} + +void ZoneBuilderBase::ligoData(LigoData &data, const ZonePosition &zonePos) +{ + m_landscapeMap.value(zonePos.region).zoneRegionObject->ligoData(data, zonePos.x, zonePos.y); +} + +void ZoneBuilderBase::setLigoData(LigoData &data, const ZonePosition &zonePos) +{ + m_landscapeMap.value(zonePos.region).zoneRegionObject->setLigoData(data, zonePos.x, zonePos.y); +} + +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; +} + +bool ZoneBuilderBase::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 ZoneBuilderBase::calcMask() +{ + sint32 x, y; + + m_minY = m_minX = 1000000; + m_maxY = m_maxX = -1000000; + + if (m_landscapeMap.size() == 0) + return; + + QMapIterator i(m_landscapeMap); + while (i.hasNext()) + { + i.next(); + const NLLIGO::CZoneRegion ®ion = i.value().zoneRegionObject->ligoZoneRegion(); + + if (m_minX > region.getMinX()) + m_minX = region.getMinX(); + if (m_minY > region.getMinY()) + m_minY = region.getMinY(); + if (m_maxX < region.getMaxX()) + m_maxX = region.getMaxX(); + if (m_maxY < region.getMaxY()) + m_maxY = region.getMaxY(); + } + + m_zoneMask.resize ((1 + m_maxX - m_minX) * (1 + m_maxY - m_minY)); + sint32 stride = (1 + m_maxX - m_minX); + for (y = m_minY; y <= m_maxY; ++y) + for (x = m_minX; x <= m_maxX; ++x) + { + m_zoneMask[x - m_minX + (y - m_minY) * stride] = true; + + QMapIterator it(m_landscapeMap); + while (it.hasNext()) + { + it.next(); + if (int(it.key()) != m_currentZoneRegion) + { + const NLLIGO::CZoneRegion ®ion = it.value().zoneRegionObject->ligoZoneRegion(); + + const std::string &rSZone = region.getName (x, y); + if ((rSZone != STRING_OUT_OF_BOUND) && (rSZone != STRING_UNUSED)) + { + m_zoneMask[x - m_minX + (y - m_minY) * stride] = false; + } + } + } + } +} + +bool ZoneBuilderBase::checkOverlaps(const NLLIGO::CZoneRegion &newZoneRegion) +{ + QMapIterator 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 */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_base.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_base.h new file mode 100644 index 000000000..509181c94 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_base.h @@ -0,0 +1,139 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +#ifndef BUILDER_ZONE_BASE_H +#define BUILDER_ZONE_BASE_H + +// Project includes +#include "zone_region_editor.h" +#include "pixmap_database.h" +#include "landscape_editor_global.h" + +// NeL includes +#include +#include + +// STL includes +#include +#include + +// Qt includes +#include +#include +#include +#include +#include +#include + +namespace LandscapeEditor +{ +class LandscapeScene; + +// 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(LandscapeScene *landscapeScene); + virtual ~ZoneBuilderBase(); + + /// Init zoneBank and init zone pixmap database + bool init(const QString &pathName, bool displayProgress = false); + + void calcMask(); + bool getZoneMask (sint32 x, sint32 y); + + /// 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); + + bool checkOverlaps(const NLLIGO::CZoneRegion &newZoneRegion); + + struct LandscapeItem + { + ZoneRegionObject *zoneRegionObject; + QGraphicsRectItem *rectItem; + }; + + sint32 m_minX, m_maxX, m_minY, m_maxY; + std::vector m_zoneMask; + + QString m_lastPathName; + + int m_currentZoneRegion; + QMap m_landscapeMap; + + PixmapDatabase *m_pixmapDatabase; + NLLIGO::CZoneBank m_zoneBank; + LandscapeScene *m_landscapeScene; +}; + +} /* namespace LandscapeEditor */ + +#endif // BUILDER_ZONE_BASE_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h index 8a31ed15d..612eaca76 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h @@ -38,7 +38,7 @@ namespace LandscapeEditor @brief @details */ -class LANDSCAPE_EDITOR_EXPORT LandscapeScene : public QGraphicsScene +class LandscapeScene : public QGraphicsScene { Q_OBJECT diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene_base.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene_base.cpp new file mode 100644 index 000000000..64d2f1af9 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene_base.cpp @@ -0,0 +1,320 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +// Project includes +#include "landscape_scene_base.h" +#include "pixmap_database.h" + +// NeL includes +#include + +// Qt includes +#include +#include +#include +#include + +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_zoneBuilder(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(ZoneBuilder *zoneBuilder) +{ + m_zoneBuilder = 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_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 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); + + NLLIGO::CZoneBankElement *zoneBankItem = m_zoneBuilder->getZoneBank().getElementByZoneName(data.zoneName); + + sint32 deltaX = 0, deltaY = 0; + + // Calculate offset for graphics item (for items with size that are larger than 1) + if ((zoneBankItem->getSizeX() > 1) || (zoneBankItem->getSizeY() > 1)) + { + sint32 sizeX = zoneBankItem->getSizeX(), sizeY = zoneBankItem->getSizeY(); + 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); + + return item; +} + +QGraphicsItem *LandscapeSceneBase::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); + + 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_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 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 */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene_base.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene_base.h new file mode 100644 index 000000000..45d4d13bf --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene_base.h @@ -0,0 +1,81 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +#ifndef LANDSCAPE_SCENE_BASE_H +#define LANDSCAPE_SCENE_BASE_H + +// Project includes +#include "zone_region_editor.h" +#include "builder_zone.h" +#include "landscape_editor_global.h" + +// NeL includes +#include + +// Qt includes +#include +#include + +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; + virtual void setZoneBuilder(ZoneBuilder *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; + ZoneBuilder *m_zoneBuilder; +}; + +} /* namespace LandscapeEditor */ + +#endif // LANDSCAPE_SCENE_BASE_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.h index abb93ab81..e6b2b950a 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.h @@ -20,13 +20,14 @@ // Project includes #include "ui_project_settings_dialog.h" +#include "landscape_editor_global.h" // Qt includes namespace LandscapeEditor { -class ProjectSettingsDialog: public QDialog +class LANDSCAPE_EDITOR_EXPORT ProjectSettingsDialog: public QDialog { Q_OBJECT From b74413dd55d5cf7699716bdb37d048d70feb8ff4 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Wed, 27 Jul 2011 19:04:46 +0300 Subject: [PATCH 31/89] Changed: #1302 Added operations creating and deleting primitives without undo/redo. --HG-- branch : gsoc2011-worldeditorqt --- .../src/plugins/world_editor/CMakeLists.txt | 1 + .../plugins/world_editor/primitive_item.cpp | 40 +- .../src/plugins/world_editor/primitive_item.h | 13 +- .../plugins/world_editor/primitives_model.cpp | 133 ++++- .../plugins/world_editor/primitives_model.h | 28 +- .../plugins/world_editor/primitives_view.cpp | 197 +++++++ .../plugins/world_editor/primitives_view.h | 74 +++ .../world_editor/world_editor_misc.cpp | 494 ++++++++++++++++++ .../plugins/world_editor/world_editor_misc.h | 55 ++ .../world_editor/world_editor_window.cpp | 28 +- .../world_editor/world_editor_window.h | 2 + .../world_editor/world_editor_window.ui | 23 +- 12 files changed, 1050 insertions(+), 38 deletions(-) create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.cpp create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.h create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_misc.cpp create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_misc.h diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/CMakeLists.txt index c8b034444..8b51838d7 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/CMakeLists.txt +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/CMakeLists.txt @@ -12,6 +12,7 @@ SET(OVQT_EXT_SYS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/../../extension_system/iplugin. SET(OVQT_PLUGIN_WORLD_EDITOR_HDR world_editor_plugin.h world_editor_window.h primitives_model.h + primitives_view.h ) SET(OVQT_PLUGIN_WORLD_EDITOR_UIS world_editor_window.ui diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.cpp index 9ec95bdaa..300a30631 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.cpp @@ -16,9 +16,14 @@ // Project includes #include "primitive_item.h" +#include "world_editor_misc.h" + +// NeL includes +#include // Qt includes -#include +#include +#include namespace WorldEditor { @@ -45,6 +50,11 @@ void BaseTreeItem::appendChild(BaseTreeItem *item) m_childItems.append(item); } +void BaseTreeItem::deleteChild(int row) +{ + delete m_childItems.takeAt(row); +} + BaseTreeItem *BaseTreeItem::child(int row) { return m_childItems.value(row); @@ -104,12 +114,13 @@ PrimitiveItem::PrimitiveItem(NLLIGO::IPrimitive *primitive, BaseTreeItem *parent m_primitive->getPropertyByName("class", className); // Set Icon - QIcon icon(QString("./old_ico/%1.ico").arg(className.c_str())); - if (primitive->getParent() == NULL) - icon = QIcon("./old_ico/root.ico"); - if (icon.isNull()) + QString nameIcon = QString("./old_ico/%1.ico").arg(className.c_str()); + QIcon icon(nameIcon); + if (!QFile::exists(nameIcon)) { - if (primitive->getNumChildren() == 0) + 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"); @@ -127,18 +138,29 @@ PrimitiveItem::~PrimitiveItem() { } -PrimitivesItem::PrimitivesItem(const QString &name, NLLIGO::CPrimitives *primitives, BaseTreeItem *parent) +NLLIGO::IPrimitive *PrimitiveItem::primitive() const +{ + return m_primitive; +} + +const NLLIGO::CPrimitiveClass *PrimitiveItem::primitiveClass() const +{ + return NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig->getPrimitiveClass(*m_primitive); +} + + +RootPrimitiveItem::RootPrimitiveItem(const QString &name, NLLIGO::CPrimitives *primitives, BaseTreeItem *parent) : PrimitiveItem(primitives->RootNode, parent), m_primitives(primitives) { setData(1, name); } /* -PrimitivesItem::PrimitivesItem(const PrimitiveItem &other) +RootPrimitiveItem::RootPrimitiveItem(const RootPrimitiveItem &other) { } */ -PrimitivesItem::~PrimitivesItem() +RootPrimitiveItem::~RootPrimitiveItem() { } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h index 26ca70670..5d00e6c92 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h @@ -21,6 +21,7 @@ // NeL includes #include +#include // Qt includes #include @@ -43,6 +44,7 @@ public: virtual ~BaseTreeItem(); void appendChild(BaseTreeItem *child); + void deleteChild(int row); BaseTreeItem *child(int row); int childCount() const; @@ -74,6 +76,9 @@ public: PrimitiveItem(const PrimitiveItem &other); virtual ~PrimitiveItem(); + NLLIGO::IPrimitive *primitive() const; + const NLLIGO::CPrimitiveClass *primitiveClass() const; + private: NLLIGO::IPrimitive *m_primitive; }; @@ -83,12 +88,12 @@ private: @brief @details */ -class PrimitivesItem: public PrimitiveItem +class RootPrimitiveItem: public PrimitiveItem { public: - PrimitivesItem(const QString &name, NLLIGO::CPrimitives *primitives, BaseTreeItem *parent); - PrimitivesItem(const PrimitiveItem &other); - virtual ~PrimitivesItem(); + RootPrimitiveItem(const QString &name, NLLIGO::CPrimitives *primitives, BaseTreeItem *parent); + RootPrimitiveItem(const RootPrimitiveItem &other); + virtual ~RootPrimitiveItem(); private: NLLIGO::CPrimitives *m_primitives; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.cpp index 8c5af6229..7a41822ab 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.cpp @@ -14,15 +14,19 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . +// Project includes +#include "primitive_item.h" +#include "primitives_model.h" +#include "world_editor_misc.h" + +// NeL includes +#include #include -#include -#include +#include +// Qt includes #include -#include "primitive_item.h" -#include "primitives_model.h" - namespace WorldEditor { @@ -136,11 +140,77 @@ int PrimitivesTreeModel::rowCount(const QModelIndex &parent) const return parentItem->childCount(); } -void PrimitivesTreeModel::addPrimitives(const QString &name, NLLIGO::CPrimitives *primitives) +NLLIGO::IPrimitive *PrimitivesTreeModel::primitive(const QModelIndex &index) +{ + NLLIGO::IPrimitive *prim = 0; + if (index.isValid()) + { + PrimitiveItem *item = static_cast(index.internalPointer()); + prim = item->primitive(); + } + return prim; +} + +const NLLIGO::CPrimitiveClass *PrimitivesTreeModel::primitiveClass(const QModelIndex &index) +{ + if (index.isValid()) + { + NLLIGO::IPrimitive *prim = primitive(index); + return ligoConfig()->getPrimitiveClass(*prim); + } + return 0; +} + +void PrimitivesTreeModel::loadPrimitive(const QString &fileName) +{ + NLLIGO::CPrimitives *primitives = new NLLIGO::CPrimitives(); + + // set the primitive context + NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = primitives; + + NLLIGO::loadXmlPrimitiveFile(*primitives, fileName.toStdString(), *NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig); + + // unset the context + NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = NULL; + + addRootPrimitive(fileName, primitives); +} + +void PrimitivesTreeModel::newPrimitiveWithoutUndo(const QString &className, uint id, const QModelIndex &parent) +{ + const NLLIGO::CPrimitiveClass *primClass = primitiveClass(parent); + float delta = 10; + + // TODO: Set the context + //CPrimitiveContext::instance().CurrentPrimitive = &_DataHierarchy[locator._LocateStack[0]].Primitives; + + NLLIGO::IPrimitive *newPrimitive = createPrimitive(className.toStdString().c_str(), className.toStdString().c_str() + , NLMISC::CVector(), delta, primClass->DynamicChildren[id].Parameters, primitive(parent)); + + // unset the context + //CPrimitiveContext::instance().CurrentPrimitive = NULL; + + if (newPrimitive != 0) + { + scanPrimitive(newPrimitive, parent); + } +} + +void PrimitivesTreeModel::deletePrimitiveWithoutUndo(const QModelIndex &index) +{ + deletePrimitive(primitive(index)); + removeRows(index.row(), index.parent()); +} + +void PrimitivesTreeModel::addRootPrimitive(const QString &name, NLLIGO::CPrimitives *primitives) { beginResetModel(); - PrimitivesItem *newPrimitives = new PrimitivesItem(name, primitives, m_rootItem); + + // Create root primitive + RootPrimitiveItem *newPrimitives = new RootPrimitiveItem(name, primitives, m_rootItem); m_rootItem->appendChild(newPrimitives); + + // Scan childs items and add in tree model for (uint i = 0; i < primitives->RootNode->getNumChildren(); ++i) { NLLIGO::IPrimitive *childPrim; @@ -150,17 +220,33 @@ void PrimitivesTreeModel::addPrimitives(const QString &name, NLLIGO::CPrimitives endResetModel(); } -void PrimitivesTreeModel::scanPrimitive(NLLIGO::IPrimitive *prim, BaseTreeItem *parent) +void PrimitivesTreeModel::scanPrimitive(NLLIGO::IPrimitive *prim, const QModelIndex &parentIndex) { -// const NLLIGO::CPrimitiveClass *primClass = NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig->getPrimitiveClass(*prim); -// nlassert (primClass); -// if (primClass->Type == NLLIGO::CPrimitiveClass::Alias) -// return; - if (prim->getClassName() == "CPrimAlias") - return; + PrimitiveItem *parent = static_cast(parentIndex.internalPointer()); + // Add in tree model + beginInsertRows(parentIndex, parent->childCount(), parent->childCount()); PrimitiveItem *newItem = new PrimitiveItem(prim, parent); parent->appendChild(newItem); + endInsertRows(); + + // Scan childs items and add in tree model + QModelIndex childIndex = index(parent->childCount() - 1, 0, parentIndex); + for (uint i = 0; i < prim->getNumChildren(); ++i) + { + NLLIGO::IPrimitive *childPrim; + prim->getChild(childPrim, i); + scanPrimitive(childPrim, childIndex); + } +} + +void PrimitivesTreeModel::scanPrimitive(NLLIGO::IPrimitive *prim, BaseTreeItem *parent) +{ + // Add in tree model + PrimitiveItem *newItem = new PrimitiveItem(prim, parent); + parent->appendChild(newItem); + + // Scan childs items and add in tree model for (uint i = 0; i < prim->getNumChildren(); ++i) { NLLIGO::IPrimitive *childPrim; @@ -169,4 +255,23 @@ void PrimitivesTreeModel::scanPrimitive(NLLIGO::IPrimitive *prim, BaseTreeItem * } } +void PrimitivesTreeModel::removeRows(int position, const QModelIndex &parent) +{ + BaseTreeItem *item = static_cast(parent.internalPointer())->child(position); + + // Delete all child items from tree model + while (item->childCount() != 0) + removeRows(0, parent.child(position, 0)); + + // Delete item + beginRemoveRows(parent, position, position); + static_cast(parent.internalPointer())->deleteChild(position); + endRemoveRows(); +} + +NLLIGO::CLigoConfig *PrimitivesTreeModel::ligoConfig() const +{ + return NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig; +} + } /* namespace WorldEditor */ \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.h index 5098d1e5e..ab4581a30 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.h @@ -18,8 +18,13 @@ #ifndef PRIMITIVES_MODEL_H #define PRIMITIVES_MODEL_H +// NeL includes +#include #include +#include +#include +// Qt includes #include #include #include @@ -28,6 +33,7 @@ namespace WorldEditor { class BaseTreeItem; +class PrimitiveItem; /** @class PrimitivesTreeModel @@ -52,11 +58,31 @@ public: int rowCount(const QModelIndex &parent = QModelIndex()) const; int columnCount(const QModelIndex &parent = QModelIndex()) const; - void addPrimitives(const QString &name, NLLIGO::CPrimitives *primitives); + // Get primitive + NLLIGO::IPrimitive *primitive(const QModelIndex &index); + + // Get primitive class + const NLLIGO::CPrimitiveClass *primitiveClass(const QModelIndex &index); + + // Load primitive from file + void loadPrimitive(const QString &fileName); + + // Create new primitive and add in tree model + void newPrimitiveWithoutUndo(const QString &className, uint id, const QModelIndex &parent); + + void deletePrimitiveWithoutUndo(const QModelIndex &index); + + NLLIGO::CLigoConfig *ligoConfig() const; private: + // Add root primitive in tree model and add all its sub-items. + void addRootPrimitive(const QString &name, NLLIGO::CPrimitives *primitives); + + void scanPrimitive(NLLIGO::IPrimitive *prim, const QModelIndex &parentIndex); void scanPrimitive(NLLIGO::IPrimitive *prim, BaseTreeItem *parent = 0); + void removeRows(int position, const QModelIndex &parent); + BaseTreeItem *m_rootItem; }; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.cpp new file mode 100644 index 000000000..2b36c7446 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.cpp @@ -0,0 +1,197 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +// Project includes +#include "primitives_view.h" +//#include "primitive_item.h" +#include "primitives_model.h" + +// NeL includes +#include +#include +#include + +// Qt includes +#include +#include + +namespace WorldEditor +{ + +PrimitivesView::PrimitivesView(QWidget *parent) + : QTreeView(parent), + m_primitivesTreeModel(0) +{ + setContextMenuPolicy(Qt::DefaultContextMenu); + + m_deleteAction = new QAction("Delete", this); + m_selectChildrenAction = new QAction("Select children", this); + m_helpAction = new QAction("Help", this); + m_showAction = new QAction("Show", this); + m_hideAction = new QAction("Hide", this); + + connect(m_deleteAction, SIGNAL(triggered()), this, SLOT(deletePrimitives())); + + connect(this, SIGNAL(clicked(QModelIndex)), this, SLOT(clickedItem(QModelIndex))); + +#ifdef Q_OS_DARWIN + setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); +#endif +} + +PrimitivesView::~PrimitivesView() +{ +} + +void PrimitivesView::setModel(PrimitivesTreeModel *model) +{ + QTreeView::setModel(model); + m_primitivesTreeModel = model; +} + +void PrimitivesView::clickedItem(const QModelIndex &index) +{ +} + +void PrimitivesView::deletePrimitives() +{ + QModelIndexList indexList = selectionModel()->selectedRows(); + + // TODO: use QPersistentModelIndex for deleting several items + m_primitivesTreeModel->deletePrimitiveWithoutUndo(indexList.first()); +} + +void PrimitivesView::addNewPrimitive(int value) +{ + QModelIndexList indexList = selectionModel()->selectedRows(); + + const NLLIGO::CPrimitiveClass *primClass = m_primitivesTreeModel->primitiveClass(indexList.first()); + + // Get class name + QString className = primClass->DynamicChildren[value].ClassName.c_str(); + + m_primitivesTreeModel->newPrimitiveWithoutUndo(className, value, indexList.first()); +} + +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); + popurMenu->addAction(m_deleteAction); + popurMenu->addAction(m_selectChildrenAction); + popurMenu->addAction(m_helpAction); + popurMenu->addSeparator(); + popurMenu->addAction(m_showAction); + popurMenu->addAction(m_hideAction); + popurMenu->addSeparator(); + + QSignalMapper *addSignalMapper = new QSignalMapper(this); + QSignalMapper *generateSignalMapper = new QSignalMapper(this); + QSignalMapper *openSignalMapper = new QSignalMapper(this); + connect(addSignalMapper, SIGNAL(mapped(int)), this, SLOT(addNewPrimitive(int))); + connect(generateSignalMapper, SIGNAL(mapped(int)), this, SLOT(generatePrimitives(int))); + //connect(openSignalMapper, SIGNAL(mapped(int)), this, SLOT(openItem(int))); + + if (indexList.size() == 1) + { + const NLLIGO::CPrimitiveClass *primClass = m_primitivesTreeModel->primitiveClass(indexList.first()); + + // What class is it ? + if (primClass && primClass->DynamicChildren.size()) + { + popurMenu->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 = popurMenu->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()) + { + popurMenu->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 = popurMenu->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 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 ()); + } + } + } + */ + } + + popurMenu->exec(event->globalPos()); + delete popurMenu; + delete addSignalMapper; + delete generateSignalMapper; + delete openSignalMapper; + event->accept(); +} + +} /* namespace WorldEditor */ \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.h new file mode 100644 index 000000000..0cfbe0318 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.h @@ -0,0 +1,74 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + + +#ifndef PRIMITIVES_VIEW_H +#define PRIMITIVES_VIEW_H + +// NeL includes +#include + +// Qt includes +#include +#include +#include +#include +#include +#include + +namespace WorldEditor +{ + +class BaseTreeItem; +class PrimitivesTreeModel; + +/** +@class PrimitivesView +@brief +@details +*/ +class PrimitivesView : public QTreeView +{ + Q_OBJECT + +public: + PrimitivesView(QWidget *parent = 0); + ~PrimitivesView(); + + virtual void setModel(PrimitivesTreeModel *model); + +private Q_SLOTS: + void clickedItem(const QModelIndex &index); + void deletePrimitives(); + void addNewPrimitive(int value); + void generatePrimitives(int value); + void openItem(int value); + +protected: + void contextMenuEvent(QContextMenuEvent *event); + + QAction *m_deleteAction; + QAction *m_selectChildrenAction; + QAction *m_helpAction; + QAction *m_showAction; + QAction *m_hideAction; + + PrimitivesTreeModel *m_primitivesTreeModel; +}; + +} /* namespace WorldEditor */ + +#endif // PRIMITIVES_VIEW_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_misc.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_misc.cpp new file mode 100644 index 000000000..824fe8be6 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_misc.cpp @@ -0,0 +1,494 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +// Project includes +#include "world_editor_misc.h" + +// NeL includes +#include +#include + +// Qt includes + +namespace WorldEditor +{ + +uint32 getUniqueId() +{ + // Wait 1 ms + sint64 time = NLMISC::CTime::getLocalTime (); + sint64 time2; + while ((time2 = NLMISC::CTime::getLocalTime ()) == time) + { + } + + return (uint32)time2; +} + +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 &initParameters) +{ + // Other parameters + for (uint p = 0; p < initParameters.size(); ++p) + { + // The property + const NLLIGO::CPrimitiveClass::CInitParameters ¶meter = 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 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 &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 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(primitive)->init(dialog.GetPathName ()); + //} + } + + // Continue ? + if (primitive) + { + // Auto init ? + if (!primClass->AutoInit) + { + // Make a vector of locator + //CDatabaseLocatorPointer locatorPtr; + //getLocator (locatorPtr, locator); + std::list locators; + //locators.push_back (const_cast (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(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 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(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 result; + std::vector *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 result; + std::vector *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; +} + +} /* namespace WorldEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_misc.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_misc.h new file mode 100644 index 000000000..4e75a3edf --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_misc.h @@ -0,0 +1,55 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +#ifndef WORLD_EDITOR_MISC_H +#define WORLD_EDITOR_MISC_H + +// Project includes + +// NeL includes +#include +#include +#include + +// Qt includes + +namespace WorldEditor +{ + +// Generate unique identificator +uint32 getUniqueId(); + +// 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 &initParameters); + +NLLIGO::IPrimitive *createPrimitive(const char *className, const char *primName, + const NLMISC::CVector &initPos, float deltaPos, + const std::vector &initParameters, + NLLIGO::IPrimitive *parent); + +// Remove the primitive and don't delete it. +//void takeAtPrimitive(NLLIGO::IPrimitive *primitive); + +void deletePrimitive(NLLIGO::IPrimitive *primitive); + +} /* namespace WorldEditor */ + +#endif // WORLD_EDITOR_MISC_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp index 8d2c0c7f1..fc1f0e248 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp @@ -20,10 +20,14 @@ #include "world_editor_constants.h" #include "primitives_model.h" +// Core #include "../core/icore.h" #include "../core/imenu_manager.h" #include "../core/core_constants.h" +// Lanscape Editor plugin +//#include "../landscape_editor/project_settings_dialog.h" + // NeL includes #include #include @@ -55,12 +59,12 @@ WorldEditorWindow::WorldEditorWindow(QWidget *parent) createMenus(); createToolBars(); -// readSettings(); + readSettings(); } WorldEditorWindow::~WorldEditorWindow() { -// writeSettings(); + writeSettings(); } QUndoStack *WorldEditorWindow::undoStack() const @@ -89,14 +93,20 @@ void WorldEditorWindow::open() void WorldEditorWindow::loadPrimitive(const QString &fileName) { - NLLIGO::CPrimitives *primitives = new NLLIGO::CPrimitives(); - - // set the primitive context - NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = primitives; - - NLLIGO::loadXmlPrimitiveFile(*primitives, fileName.toStdString(), *NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig); + m_primitivesModel->loadPrimitive(fileName); +} - m_primitivesModel->addPrimitives(fileName, primitives); +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() diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h index 8311ffcc6..39e741716 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h @@ -43,6 +43,8 @@ public Q_SLOTS: void open(); private Q_SLOTS: + void openProjectSettings(); + private: void createMenus(); void createToolBars(); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui index 6f597ca2a..179a78830 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui @@ -61,7 +61,23 @@ 3 - + + + true + + + QAbstractItemView::ExtendedSelection + + + true + + + true + + + 250 + + @@ -83,6 +99,11 @@ QGraphicsView
../landscape_editor/landscape_view.h
+ + WorldEditor::PrimitivesView + QTreeView +
primitives_view.h
+
From d0e4d176563afab1e37d855e872684c83fb14280 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Sat, 30 Jul 2011 21:50:30 +0300 Subject: [PATCH 32/89] Changed: #1301 Updated LandscapeSceneBase and ZoneBuilderBase classes for world editor plugin. --HG-- branch : gsoc2011-worldeditorqt --- .../landscape_editor/builder_zone_base.cpp | 120 ++---------------- .../landscape_editor/builder_zone_base.h | 26 ++-- .../landscape_editor/landscape_scene_base.cpp | 27 ++-- .../landscape_editor/landscape_scene_base.h | 8 +- .../landscape_editor/zone_region_editor.cpp | 38 +----- .../landscape_editor/zone_region_editor.h | 38 +++++- 6 files changed, 72 insertions(+), 185 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_base.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_base.cpp index a8fc40cab..eaea3d447 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_base.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_base.cpp @@ -17,8 +17,9 @@ // Project includes #include "builder_zone_base.h" -#include "list_zones_widget.h" -#include "landscape_actions.h" +#include "landscape_scene_base.h" +#include "zone_region_editor.h" +#include "pixmap_database.h" // NeL includes #include @@ -32,12 +33,11 @@ namespace LandscapeEditor { int NewLandId = 0; -ZoneBuilderBase::ZoneBuilderBase(LandscapeScene *landscapeScene) - : m_currentZoneRegion(-1), - m_pixmapDatabase(0), - m_landscapeScene(landscapeScene) +ZoneBuilderBase::ZoneBuilderBase(LandscapeSceneBase *landscapeScene) + : m_pixmapDatabase(0), + m_landscapeSceneBase(landscapeScene) { - nlassert(m_landscapeScene); + nlassert(m_landscapeSceneBase); m_pixmapDatabase = new PixmapDatabase(); m_lastPathName = ""; } @@ -77,23 +77,7 @@ bool ZoneBuilderBase::init(const QString &pathName, bool displayProgress) return true; } -int ZoneBuilderBase::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(NewLandId, landItem); - if (m_currentZoneRegion == -1) - setCurrentZoneRegion(NewLandId); - - calcMask(); - return NewLandId++; -} - -int ZoneBuilderBase::createZoneRegion(const QString &fileName) +int ZoneBuilderBase::loadZoneRegion(const QString &fileName) { LandscapeItem landItem; landItem.zoneRegionObject = new ZoneRegionObject(); @@ -107,13 +91,10 @@ int ZoneBuilderBase::createZoneRegion(const QString &fileName) // landItem.builderZoneRegion = new BuilderZoneRegion(LandCounter); // landItem.builderZoneRegion->init(this); - m_landscapeScene->addZoneRegion(landItem.zoneRegionObject->ligoZoneRegion()); - landItem.rectItem = m_landscapeScene->createLayerBlackout(landItem.zoneRegionObject->ligoZoneRegion()); + m_landscapeSceneBase->addZoneRegion(landItem.zoneRegionObject->ligoZoneRegion()); +// landItem.rectItem = m_landscapeScene->createLayerBlackout(landItem.zoneRegionObject->ligoZoneRegion()); m_landscapeMap.insert(NewLandId, landItem); - if (m_currentZoneRegion == -1) - setCurrentZoneRegion(NewLandId); - calcMask(); return NewLandId++; } @@ -122,9 +103,7 @@ void ZoneBuilderBase::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()); + 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); @@ -134,34 +113,6 @@ void ZoneBuilderBase::deleteZoneRegion(int id) nlwarning("Landscape (id %i) not found", id); } -void ZoneBuilderBase::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 ZoneBuilderBase::currentIdZoneRegion() const -{ - return m_currentZoneRegion; -} - -ZoneRegionObject *ZoneBuilderBase::currentZoneRegion() const -{ - return m_landscapeMap.value(m_currentZoneRegion).zoneRegionObject; -} - int ZoneBuilderBase::countZoneRegion() const { return m_landscapeMap.size(); @@ -172,16 +123,6 @@ ZoneRegionObject *ZoneBuilderBase::zoneRegion(int id) const return m_landscapeMap.value(id).zoneRegionObject; } -void ZoneBuilderBase::ligoData(LigoData &data, const ZonePosition &zonePos) -{ - m_landscapeMap.value(zonePos.region).zoneRegionObject->ligoData(data, zonePos.x, zonePos.y); -} - -void ZoneBuilderBase::setLigoData(LigoData &data, const ZonePosition &zonePos) -{ - m_landscapeMap.value(zonePos.region).zoneRegionObject->setLigoData(data, zonePos.x, zonePos.y); -} - bool ZoneBuilderBase::initZoneBank (const QString &pathName) { QDir *dir = new QDir(pathName); @@ -212,23 +153,8 @@ QString ZoneBuilderBase::dataPath() const return m_lastPathName; } -bool ZoneBuilderBase::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 ZoneBuilderBase::calcMask() { - sint32 x, y; - m_minY = m_minX = 1000000; m_maxY = m_maxX = -1000000; @@ -250,30 +176,6 @@ void ZoneBuilderBase::calcMask() 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 it(m_landscapeMap); - while (it.hasNext()) - { - it.next(); - if (int(it.key()) != m_currentZoneRegion) - { - const NLLIGO::CZoneRegion ®ion = it.value().zoneRegionObject->ligoZoneRegion(); - - const std::string &rSZone = region.getName (x, y); - if ((rSZone != STRING_OUT_OF_BOUND) && (rSZone != STRING_UNUSED)) - { - m_zoneMask[x - m_minX + (y - m_minY) * stride] = false; - } - } - } - } } bool ZoneBuilderBase::checkOverlaps(const NLLIGO::CZoneRegion &newZoneRegion) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_base.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_base.h index 509181c94..249f11a73 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_base.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_base.h @@ -19,8 +19,6 @@ #define BUILDER_ZONE_BASE_H // Project includes -#include "zone_region_editor.h" -#include "pixmap_database.h" #include "landscape_editor_global.h" // NeL includes @@ -41,7 +39,9 @@ namespace LandscapeEditor { -class LandscapeScene; +class LandscapeSceneBase; +class PixmapDatabase; +class ZoneRegionObject; // Data struct ZonePosition @@ -75,27 +75,18 @@ PixmapDatabase contains the graphics for the zones class LANDSCAPE_EDITOR_EXPORT ZoneBuilderBase { public: - ZoneBuilderBase(LandscapeScene *landscapeScene); + ZoneBuilderBase(LandscapeSceneBase *landscapeScene); virtual ~ZoneBuilderBase(); /// Init zoneBank and init zone pixmap database bool init(const QString &pathName, bool displayProgress = false); - void calcMask(); - bool getZoneMask (sint32 x, sint32 y); - /// Zone Region /// @{ - int createZoneRegion(); - int createZoneRegion(const QString &fileName); + int loadZoneRegion(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 @@ -113,25 +104,24 @@ 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; - QGraphicsRectItem *rectItem; }; sint32 m_minX, m_maxX, m_minY, m_maxY; - std::vector m_zoneMask; QString m_lastPathName; - int m_currentZoneRegion; QMap m_landscapeMap; PixmapDatabase *m_pixmapDatabase; NLLIGO::CZoneBank m_zoneBank; - LandscapeScene *m_landscapeScene; + LandscapeSceneBase *m_landscapeSceneBase; }; } /* namespace LandscapeEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene_base.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene_base.cpp index 64d2f1af9..7946fffbc 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene_base.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene_base.cpp @@ -29,13 +29,12 @@ 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 char *const LAYER_BLACKOUT_NAME = "blackout"; const int MAX_SCENE_WIDTH = 256; const int MAX_SCENE_HEIGHT = 256; @@ -43,7 +42,7 @@ const int MAX_SCENE_HEIGHT = 256; LandscapeSceneBase::LandscapeSceneBase(int sizeCell, QObject *parent) : QGraphicsScene(parent), m_cellSize(sizeCell), - m_zoneBuilder(0) + m_zoneBuilderBase(0) { setSceneRect(QRectF(0, m_cellSize, MAX_SCENE_WIDTH * m_cellSize, MAX_SCENE_HEIGHT * m_cellSize)); } @@ -57,9 +56,9 @@ int LandscapeSceneBase::cellSize() const return m_cellSize; } -void LandscapeSceneBase::setZoneBuilder(ZoneBuilder *zoneBuilder) +void LandscapeSceneBase::setZoneBuilder(ZoneBuilderBase *zoneBuilder) { - m_zoneBuilder = zoneBuilder; + m_zoneBuilderBase = zoneBuilder; } QGraphicsItem *LandscapeSceneBase::createItemZone(const LigoData &data, const ZonePosition &zonePos) @@ -70,11 +69,11 @@ QGraphicsItem *LandscapeSceneBase::createItemZone(const LigoData &data, const Zo if (data.zoneName == STRING_UNUSED) return createItemEmptyZone(zonePos); - if ((m_zoneBuilder == 0) || (data.zoneName.empty())) + if ((m_zoneBuilderBase == 0) || (data.zoneName.empty())) return 0; // Get image from pixmap database - QPixmap *pixmap = m_zoneBuilder->pixmapDatabase()->pixmap(QString(data.zoneName.c_str())); + QPixmap *pixmap = m_zoneBuilderBase->pixmapDatabase()->pixmap(QString(data.zoneName.c_str())); if (pixmap == 0) return 0; @@ -98,7 +97,7 @@ QGraphicsItem *LandscapeSceneBase::createItemZone(const LigoData &data, const Zo // Enable bilinear filtering item->setTransformationMode(Qt::SmoothTransformation); - NLLIGO::CZoneBankElement *zoneBankItem = m_zoneBuilder->getZoneBank().getElementByZoneName(data.zoneName); + NLLIGO::CZoneBankElement *zoneBankItem = m_zoneBuilderBase->getZoneBank().getElementByZoneName(data.zoneName); sint32 deltaX = 0, deltaY = 0; @@ -156,7 +155,7 @@ QGraphicsItem *LandscapeSceneBase::createItemZone(const LigoData &data, const Zo 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->setScale(float(m_cellSize) / m_zoneBuilderBase->pixmapDatabase()->textureSize()); item->setData(ZONE_NAME, QString(data.zoneName.c_str())); @@ -168,14 +167,14 @@ QGraphicsItem *LandscapeSceneBase::createItemZone(const LigoData &data, const Zo QGraphicsItem *LandscapeSceneBase::createItemEmptyZone(const ZonePosition &zonePos) { - if (m_zoneBuilder == 0) + if (m_zoneBuilderBase == 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)); + QPixmap *pixmap = m_zoneBuilderBase->pixmapDatabase()->pixmap(QString(STRING_UNUSED)); if (pixmap == 0) return 0; @@ -188,7 +187,7 @@ QGraphicsItem *LandscapeSceneBase::createItemEmptyZone(const ZonePosition &zoneP 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()); + item->setScale(float(m_cellSize) / m_zoneBuilderBase->pixmapDatabase()->textureSize()); // for not full item zone item->setZValue(LAYER_EMPTY_ZONES); @@ -249,7 +248,7 @@ void LandscapeSceneBase::delZoneRegion(const NLLIGO::CZoneRegion &zoneRegion) void LandscapeSceneBase::snapshot(const QString &fileName, int width, int height, const QRectF &landRect) { - if (m_zoneBuilder == 0) + if (m_zoneBuilderBase == 0) return; // Create image @@ -291,7 +290,7 @@ void LandscapeSceneBase::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) m_mouseButton = mouseEvent->button(); } -void LandscapeSceneBase::mouseMoveEvent(QGraphicsSceneMouseEvent * mouseEvent) +void LandscapeSceneBase::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) { m_mouseX = mouseEvent->scenePos().x(); m_mouseY = mouseEvent->scenePos().y() - m_cellSize; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene_base.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene_base.h index 45d4d13bf..acfc0f9f7 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene_base.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene_base.h @@ -18,9 +18,9 @@ #define LANDSCAPE_SCENE_BASE_H // Project includes -#include "zone_region_editor.h" -#include "builder_zone.h" #include "landscape_editor_global.h" +#include "builder_zone_base.h" +#include "zone_region_editor.h" // NeL includes #include @@ -46,7 +46,7 @@ public: virtual ~LandscapeSceneBase(); int cellSize() const; - virtual void setZoneBuilder(ZoneBuilder *zoneBuilder); + void setZoneBuilder(ZoneBuilderBase *zoneBuilder); QGraphicsItem *createItemZone(const LigoData &data, const ZonePosition &zonePos); QGraphicsItem *createItemEmptyZone(const ZonePosition &zonePos); @@ -73,7 +73,7 @@ private: qreal m_mouseX, m_mouseY; sint32 m_posX, m_posY; Qt::MouseButton m_mouseButton; - ZoneBuilder *m_zoneBuilder; + ZoneBuilderBase *m_zoneBuilderBase; }; } /* namespace LandscapeEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.cpp index 399d39496..a9699acee 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.cpp @@ -30,40 +30,6 @@ namespace LandscapeEditor { -LigoData::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 LigoData::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]); -} - ZoneRegionObject::ZoneRegionObject() { m_fileName = ""; @@ -92,7 +58,7 @@ bool ZoneRegionObject::load(const std::string &fileName) result = false; } } - catch (NLMISC::Exception& e) + catch (NLMISC::Exception &e) { nlwarning("Error reading file %s : %s", fileName.c_str(), e.what ()); result = false; @@ -132,7 +98,7 @@ bool ZoneRegionObject::save() result = false; } } - catch (NLMISC::Exception& e) + catch (NLMISC::Exception &e) { nlwarning("Error writing file %s : %s", m_fileName.c_str(), e.what()); result = false; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.h index 9081d7002..91b2d66c1 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.h @@ -19,6 +19,7 @@ #define LANDSCAPE_EDITOR_H // Project includes +#include "landscape_editor_global.h" // NeL includes #include @@ -43,9 +44,38 @@ struct LigoData std::string sharingMatNames[4]; uint8 sharingCutEdges[4]; - LigoData(); - - bool operator!= (const LigoData& other) const; + 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]); + } }; /** @@ -53,7 +83,7 @@ struct LigoData @brief @details */ -class ZoneRegionObject +class LANDSCAPE_EDITOR_EXPORT ZoneRegionObject { public: ZoneRegionObject(); From 55f7ee692f7993536ed8f13546f0245d2bfcb60a Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Sat, 30 Jul 2011 21:52:26 +0300 Subject: [PATCH 33/89] Changed: #1301 Fix typos in comments/code. --HG-- branch : gsoc2011-worldeditorqt --- .../landscape_editor/builder_zone_region.cpp | 7 +++---- .../landscape_editor/builder_zone_region.h | 3 +-- .../landscape_editor_constants.h | 18 +++++++++--------- .../landscape_editor/landscape_scene.cpp | 4 ++-- .../landscape_editor/list_zones_model.h | 2 +- .../plugins/landscape_editor/pixmap_database.h | 2 +- 6 files changed, 17 insertions(+), 19 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.cpp index b294ce97b..3f787e6b0 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.cpp @@ -1,6 +1,5 @@ // Object Viewer Qt - MMORPG Framework // Copyright (C) 2010 Winch Gate Property Limited -// Copyright (C) 2011 Dzmitry Kamiahin // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as @@ -168,12 +167,12 @@ public: return m_elements[m].y; } - BuilderZoneRegion* getBuilderZoneRegion(uint32 m) + BuilderZoneRegion *getBuilderZoneRegion(uint32 m) { return m_elements[m].builderZoneRegion; } - const std::string& getMat (uint32 m) + const std::string &getMat (uint32 m) { return m_elements[m].matPut; } @@ -804,7 +803,7 @@ void BuilderZoneRegion::addTransition (sint32 x, sint32 y, uint8 rot, uint8 flip } } -void BuilderZoneRegion::addToUpdateAndCreate(BuilderZoneRegion* builderZoneRegion, sint32 sharePos, sint32 x, sint32 y, const std::string &newMat, void *pInt1, void *pInt2) +void BuilderZoneRegion::addToUpdateAndCreate(BuilderZoneRegion *builderZoneRegion, sint32 sharePos, sint32 x, sint32 y, const std::string &newMat, void *pInt1, void *pInt2) { const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->ligoZoneRegion(); ToUpdate *ptCreate = reinterpret_cast(pInt1); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.h index 63656d643..6de45da50 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.h @@ -1,6 +1,5 @@ // Object Viewer Qt - MMORPG Framework // Copyright (C) 2010 Winch Gate Property Limited -// Copyright (C) 2011 Dzmitry Kamiahin // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as @@ -70,7 +69,7 @@ private: 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 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); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_constants.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_constants.h index 0cdf6d3cd..76b91dad5 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_constants.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_constants.h @@ -22,19 +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_WINDOW_STATE = "LandscapeWindowState"; -const char * const LANDSCAPE_WINDOW_GEOMETRY = "LandscapeWindowGeometry"; -const char * const LANDSCAPE_DATA_DIRECTORY = "LandscapeDataDirectory"; -const char * const LANDSCAPE_USE_OPENGL = "LandscapeUseOpenGL"; +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_ZONE_ITEM = ":/icons/ic_nel_zone.png"; -const char * const ICON_LANDSCAPE_ZONES = ":/icons/ic_nel_zones.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 diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp index 67485158d..bdbe54f8c 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp @@ -35,7 +35,7 @@ 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 char *const LAYER_BLACKOUT_NAME = "blackout"; const int MAX_SCENE_WIDTH = 256; const int MAX_SCENE_HEIGHT = 256; @@ -323,7 +323,7 @@ void LandscapeScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) QGraphicsScene::mousePressEvent(mouseEvent); } -void LandscapeScene::mouseMoveEvent(QGraphicsSceneMouseEvent * mouseEvent) +void LandscapeScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) { qreal x = mouseEvent->scenePos().x(); qreal y = mouseEvent->scenePos().y(); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_model.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_model.h index 475416887..6c53ab4bc 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_model.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_model.h @@ -70,7 +70,7 @@ private: QPixmap *getPixmap(const QString &zoneName) const; int m_scaleRatio; - QMap m_pixmapMap; + QMap m_pixmapMap; QStringList m_listNames; }; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.h index fc90fe180..85b0f180e 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.h @@ -61,7 +61,7 @@ public: private: int m_textureSize; - QMap m_pixmapMap; + QMap m_pixmapMap; }; } /* namespace LandscapeEditor */ From c5dbe3cc82ea40025c7ca69cd55f9f0ee56347fa Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Sat, 30 Jul 2011 21:56:21 +0300 Subject: [PATCH 34/89] Changed: #1302 Fix typos in comments/code. --HG-- branch : gsoc2011-worldeditorqt --- .../plugins/world_editor/primitives_view.cpp | 6 ------ .../src/plugins/world_editor/primitives_view.h | 1 - .../world_editor/world_editor_constants.h | 18 +++++++++--------- 3 files changed, 9 insertions(+), 16 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.cpp index 2b36c7446..0cc4e5e52 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.cpp @@ -45,8 +45,6 @@ PrimitivesView::PrimitivesView(QWidget *parent) connect(m_deleteAction, SIGNAL(triggered()), this, SLOT(deletePrimitives())); - connect(this, SIGNAL(clicked(QModelIndex)), this, SLOT(clickedItem(QModelIndex))); - #ifdef Q_OS_DARWIN setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); #endif @@ -62,10 +60,6 @@ void PrimitivesView::setModel(PrimitivesTreeModel *model) m_primitivesTreeModel = model; } -void PrimitivesView::clickedItem(const QModelIndex &index) -{ -} - void PrimitivesView::deletePrimitives() { QModelIndexList indexList = selectionModel()->selectedRows(); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.h index 0cfbe0318..b0381b5bf 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.h @@ -51,7 +51,6 @@ public: virtual void setModel(PrimitivesTreeModel *model); private Q_SLOTS: - void clickedItem(const QModelIndex &index); void deletePrimitives(); void addNewPrimitive(int value); void generatePrimitives(int value); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_constants.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_constants.h index a54b82cb1..cb1abf21e 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_constants.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_constants.h @@ -22,19 +22,19 @@ namespace WorldEditor { namespace Constants { -const char * const WORLD_EDITOR_PLUGIN = "WorldEditor"; +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"; +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"; +const char *const ICON_WORLD_EDITOR = ":/icons/ic_nel_world_editor.png"; } // namespace Constants From 14272b5e79e79bd0bc178050d7b1a311e1b048c0 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Sat, 30 Jul 2011 21:58:48 +0300 Subject: [PATCH 35/89] Changed: #1302 Added world edit mode toolbar. --HG-- branch : gsoc2011-worldeditorqt --- .../world_editor/icons/ic_nel_move.png | Bin 0 -> 3170 bytes .../world_editor/icons/ic_nel_rotate.png | Bin 0 -> 4089 bytes .../world_editor/icons/ic_nel_scale.png | Bin 0 -> 4299 bytes .../world_editor/icons/ic_nel_select.png | Bin 0 -> 3182 bytes .../world_editor/icons/ic_nel_turn.png | Bin 0 -> 2747 bytes .../src/plugins/world_editor/world_editor.qrc | 5 + .../world_editor/world_editor_window.cpp | 28 +++ .../world_editor/world_editor_window.h | 2 + .../world_editor/world_editor_window.ui | 187 +++++++++++++++++- 9 files changed, 220 insertions(+), 2 deletions(-) create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/icons/ic_nel_move.png create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/icons/ic_nel_rotate.png create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/icons/ic_nel_scale.png create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/icons/ic_nel_select.png create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/icons/ic_nel_turn.png diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/icons/ic_nel_move.png b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/icons/ic_nel_move.png new file mode 100644 index 0000000000000000000000000000000000000000..7039bd070067c121c446c52b291dd1b0a30901e4 GIT binary patch literal 3170 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 IM6N<$f`VA}i2wiq literal 0 HcmV?d00001 diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/icons/ic_nel_rotate.png b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/icons/ic_nel_rotate.png new file mode 100644 index 0000000000000000000000000000000000000000..73a0be2fe53e26e96b41a42c442c5462de39bd95 GIT binary patch literal 4089 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 literal 0 HcmV?d00001 diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/icons/ic_nel_scale.png b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/icons/ic_nel_scale.png new file mode 100644 index 0000000000000000000000000000000000000000..e76150ab4b4e0043d081774fd2f4e9d25fab1233 GIT binary patch literal 4299 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 literal 0 HcmV?d00001 diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/icons/ic_nel_select.png b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/icons/ic_nel_select.png new file mode 100644 index 0000000000000000000000000000000000000000..9a677b8a668b175260825db8a6614c1d456c17f2 GIT binary patch literal 3182 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 literal 0 HcmV?d00001 diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/icons/ic_nel_turn.png b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/icons/ic_nel_turn.png new file mode 100644 index 0000000000000000000000000000000000000000..b03cb0fd0631c078f9e308f9fd9c7b67dceea168 GIT binary patch literal 2747 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 BBOd?& literal 0 HcmV?d00001 diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor.qrc b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor.qrc index f7c54fd5f..02ffcbe00 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor.qrc +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor.qrc @@ -1,5 +1,10 @@ + icons/ic_nel_select.png + icons/ic_nel_scale.png + icons/ic_nel_rotate.png + icons/ic_nel_move.png + icons/ic_nel_turn.png icons/ic_nel_world_editor.png diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp index fc1f0e248..7ddb5484c 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp @@ -40,6 +40,7 @@ // Qt includes #include +#include #include namespace WorldEditor @@ -54,12 +55,28 @@ WorldEditorWindow::WorldEditorWindow(QWidget *parent) m_ui.setupUi(this); m_undoStack = new QUndoStack(this); + 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); createMenus(); createToolBars(); readSettings(); + + connect(m_ui.newWorldEditAction, SIGNAL(triggered()), this, SLOT(newWorldEditFile())); + connect(m_ui.saveWorldEditAction, SIGNAL(triggered()), this, SLOT(saveAllWorldEditFiles())); + } WorldEditorWindow::~WorldEditorWindow() @@ -96,6 +113,14 @@ void WorldEditorWindow::loadPrimitive(const QString &fileName) m_primitivesModel->loadPrimitive(fileName); } +void WorldEditorWindow::newWorldEditFile() +{ +} + +void WorldEditorWindow::saveAllWorldEditFiles() +{ +} + void WorldEditorWindow::openProjectSettings() { /* @@ -119,8 +144,11 @@ 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); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h index 39e741716..1b2937dad 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h @@ -43,6 +43,8 @@ public Q_SLOTS: void open(); private Q_SLOTS: + void newWorldEditFile(); + void saveAllWorldEditFiles(); void openProjectSettings(); private: diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui index 179a78830..331dc34ff 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui @@ -45,10 +45,19 @@ false - - + + + + + + + + + + Primitives + 2 @@ -82,6 +91,23 @@ + + + toolBar + + + TopToolBarArea + + + false + + + + + + + + loadPrimitive @@ -92,6 +118,162 @@ newPrimitive + + + + :/icons/ic_nel_zonel.png:/icons/ic_nel_zonel.png + + + loadLand + + + + + + :/icons/ic_nel_landscape_settings.png:/icons/ic_nel_landscape_settings.png + + + LandSettings + + + + + true + + + S/H Land + + + + + true + + + S/H Primitives + + + + + true + + + S/H Layers + + + + + true + + + S/H Details + + + + + true + + + + :/icons/ic_grid.png:/icons/ic_grid.png + + + S/H Grid + + + + + true + + + S/H Grid points + + + + + New World Edit file + + + + + Save World Edit file + + + + + true + + + + :/icons/ic_nel_select.png:/icons/ic_nel_select.png + + + Select + + + + + true + + + + :/icons/ic_nel_move.png:/icons/ic_nel_move.png + + + Move + + + + + true + + + + :/icons/ic_nel_rotate.png:/icons/ic_nel_rotate.png + + + Rotate + + + + + true + + + + :/icons/ic_nel_scale.png:/icons/ic_nel_scale.png + + + Scale + + + + + true + + + + :/icons/ic_nel_turn.png:/icons/ic_nel_turn.png + + + Turn + + + + + true + + + Radius + + + + + true + + + Edit points + + @@ -107,6 +289,7 @@ + From 3e9e103dea0374bbeec5236210654f71ab4dc464 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Sat, 30 Jul 2011 22:32:06 +0300 Subject: [PATCH 36/89] Changed: #1302 Added 2d render in world editor plugin. --HG-- branch : gsoc2011-worldeditorqt --- .../src/plugins/world_editor/CMakeLists.txt | 1 + .../world_editor/world_editor_scene.cpp | 71 +++++++++++++++++++ .../plugins/world_editor/world_editor_scene.h | 57 +++++++++++++++ .../world_editor/world_editor_window.cpp | 10 +++ .../world_editor/world_editor_window.h | 8 +++ 5 files changed, 147 insertions(+) create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/CMakeLists.txt index 8b51838d7..1e41175bd 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/CMakeLists.txt +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/CMakeLists.txt @@ -11,6 +11,7 @@ SET(OVQT_EXT_SYS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/../../extension_system/iplugin. SET(OVQT_PLUGIN_WORLD_EDITOR_HDR world_editor_plugin.h world_editor_window.h + world_editor_scene.h primitives_model.h primitives_view.h ) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp new file mode 100644 index 000000000..2c4c41065 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp @@ -0,0 +1,71 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +// Project includes +#include "world_editor_scene.h" + +// NeL includes +#include + +// Qt includes +#include +#include +#include +#include + +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 */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h new file mode 100644 index 000000000..84dba333c --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h @@ -0,0 +1,57 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +#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 diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp index 7ddb5484c..fd9f9c755 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp @@ -19,6 +19,7 @@ #include "world_editor_window.h" #include "world_editor_constants.h" #include "primitives_model.h" +#include "world_editor_scene.h" // Core #include "../core/icore.h" @@ -26,6 +27,7 @@ #include "../core/core_constants.h" // Lanscape Editor plugin +#include "../landscape_editor/builder_zone_base.h" //#include "../landscape_editor/project_settings_dialog.h" // NeL includes @@ -55,6 +57,12 @@ WorldEditorWindow::WorldEditorWindow(QWidget *parent) m_ui.setupUi(this); m_undoStack = new QUndoStack(this); + m_worldEditorScene = new WorldEditorScene(160, 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); @@ -82,6 +90,8 @@ WorldEditorWindow::WorldEditorWindow(QWidget *parent) WorldEditorWindow::~WorldEditorWindow() { writeSettings(); + + delete m_zoneBuilderBase; } QUndoStack *WorldEditorWindow::undoStack() const diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h index 1b2937dad..99768736b 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h @@ -24,9 +24,15 @@ // Qt includes #include +namespace LandscapeEditor +{ +class ZoneBuilderBase; +} + namespace WorldEditor { class PrimitivesTreeModel; +class WorldEditorScene; class WorldEditorWindow: public QMainWindow { @@ -57,6 +63,8 @@ private: PrimitivesTreeModel *m_primitivesModel; QUndoStack *m_undoStack; + WorldEditorScene *m_worldEditorScene; + LandscapeEditor::ZoneBuilderBase *m_zoneBuilderBase; Ui::WorldEditorWindow m_ui; }; /* class WorldEditorWindow */ From a41a662edbc16c03f5ec0e04a1f3714b9f2b909a Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Tue, 2 Aug 2011 16:10:12 +0300 Subject: [PATCH 37/89] Changed: #1301 Improved ZoneBuilderBase for using in undo/redo commands. --HG-- branch : gsoc2011-worldeditorqt --- .../plugins/landscape_editor/builder_zone_base.cpp | 9 ++++++--- .../plugins/landscape_editor/builder_zone_base.h | 2 +- .../src/plugins/landscape_editor/landscape_view.cpp | 13 +++++++++++-- .../src/plugins/landscape_editor/landscape_view.h | 4 ++-- .../plugins/landscape_editor/pixmap_database.cpp | 4 +--- 5 files changed, 21 insertions(+), 11 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_base.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_base.cpp index eaea3d447..958aee640 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_base.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_base.cpp @@ -77,7 +77,7 @@ bool ZoneBuilderBase::init(const QString &pathName, bool displayProgress) return true; } -int ZoneBuilderBase::loadZoneRegion(const QString &fileName) +int ZoneBuilderBase::loadZoneRegion(const QString &fileName, int defaultId) { LandscapeItem landItem; landItem.zoneRegionObject = new ZoneRegionObject(); @@ -88,15 +88,18 @@ int ZoneBuilderBase::loadZoneRegion(const QString &fileName) 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(NewLandId, landItem); + m_landscapeMap.insert(id, landItem); calcMask(); - return NewLandId++; + return id; } void ZoneBuilderBase::deleteZoneRegion(int id) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_base.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_base.h index 249f11a73..4c9e501eb 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_base.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_base.h @@ -83,7 +83,7 @@ public: /// Zone Region /// @{ - int loadZoneRegion(const QString &fileName); + int loadZoneRegion(const QString &fileName, int defaultId = -1); void deleteZoneRegion(int id); int countZoneRegion() const; ZoneRegionObject *zoneRegion(int id) const; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp index 263417204..c254fd65d 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp @@ -1,5 +1,4 @@ // Object Viewer Qt - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited // Copyright (C) 2011 Dzmitry Kamiahin // // This program is free software: you can redistribute it and/or modify @@ -34,9 +33,10 @@ namespace LandscapeEditor LandscapeView::LandscapeView(QWidget *parent) : QGraphicsView(parent), m_visibleGrid(true), + m_visibleText(true), m_moveMouse(false) { - setDragMode(ScrollHandDrag); + //setDragMode(ScrollHandDrag); setTransformationAnchor(AnchorUnderMouse); setBackgroundBrush(QBrush(Qt::lightGray)); //setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate); @@ -62,6 +62,12 @@ void LandscapeView::setVisibleGrid(bool visible) scene()->update(); } +void LandscapeView::setVisibleText(bool visible) +{ + m_visibleText = visible; + scene()->update(); +} + void LandscapeView::wheelEvent(QWheelEvent *event) { double numDegrees = event->delta() / 8.0; @@ -118,6 +124,9 @@ void LandscapeView::drawForeground(QPainter *painter, const QRectF &rect) 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)); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h index 0673db82c..20e7ee1bc 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h @@ -1,5 +1,4 @@ // Object Viewer Qt - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited // Copyright (C) 2011 Dzmitry Kamiahin // // This program is free software: you can redistribute it and/or modify @@ -40,6 +39,7 @@ public: public Q_SLOTS: void setVisibleGrid(bool visible); + void setVisibleText(bool visible); private Q_SLOTS: protected: @@ -53,7 +53,7 @@ protected: void drawZoneNames(QPainter *painter, const QRectF &rect); private: - bool m_visibleGrid; + bool m_visibleGrid, m_visibleText; int m_numSteps, m_maxSteps; int m_cellSize; bool m_moveMouse; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.cpp index f0e2859f6..52d8e04f3 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.cpp @@ -1,5 +1,4 @@ // Object Viewer Qt - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited // Copyright (C) 2011 Dzmitry Kamiahin // // This program is free software: you can redistribute it and/or modify @@ -52,9 +51,8 @@ bool PixmapDatabase::loadPixmaps(const QString &zonePath, NLLIGO::CZoneBank &zon zoneBank.getCategoryValues ("zone", listNames); if (displayProgress) { - progressDialog = new QProgressDialog(); + progressDialog = new QProgressDialog("Loading ligo zones.", "Cancel", 0, listNames.size()); progressDialog->show(); - progressDialog->setRange(0, listNames.size()); } for (uint i = 0; i < listNames.size(); ++i) From ebd48bccc1910724804e1e3353ad1783e9168671 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Wed, 3 Aug 2011 18:43:00 +0300 Subject: [PATCH 38/89] Changed: #1302 Added new utils functions. --HG-- branch : gsoc2011-worldeditorqt --- .../world_editor/world_editor_misc.cpp | 200 +++++++++++++++++- .../plugins/world_editor/world_editor_misc.h | 27 ++- 2 files changed, 225 insertions(+), 2 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_misc.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_misc.cpp index 824fe8be6..e06332deb 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_misc.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_misc.cpp @@ -20,12 +20,51 @@ // NeL includes #include +#include +#include +#include +#include +#include #include + // 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() { @@ -39,6 +78,148 @@ uint32 getUniqueId() 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); @@ -265,7 +446,7 @@ NLLIGO::IPrimitive *createPrimitive(const char *className, const char *primName, // Make a vector of locator //CDatabaseLocatorPointer locatorPtr; //getLocator (locatorPtr, locator); - std::list locators; + std::list locators; //locators.push_back (const_cast (locatorPtr.Primitive)); // Yes, go @@ -491,4 +672,21 @@ bool updateDefaultValues(NLLIGO::IPrimitive *primitive) 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 */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_misc.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_misc.h index 4e75a3edf..ea6a59f58 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_misc.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_misc.h @@ -25,14 +25,34 @@ #include #include -// Qt includes +// STL includes +#include +#include + +#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 WorldEditItem; +typedef std::vector 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); @@ -50,6 +70,11 @@ NLLIGO::IPrimitive *createPrimitive(const char *className, const char *primName, void deletePrimitive(NLLIGO::IPrimitive *primitive); +bool updateDefaultValues(NLLIGO::IPrimitive *primitive); + +bool recursiveUpdateDefaultValues(NLLIGO::IPrimitive *primitive); + +} /* namespace Utils */ } /* namespace WorldEditor */ #endif // WORLD_EDITOR_MISC_H From 7ab6c38496079ad403ee8b3398b54a5dd576f76d Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Wed, 3 Aug 2011 18:45:14 +0300 Subject: [PATCH 39/89] Changed: #1302 Redesigned the primitives database and added undo\redo commands for database. --HG-- branch : gsoc2011-worldeditorqt --- .../plugins/world_editor/primitive_item.cpp | 196 +++++++--- .../src/plugins/world_editor/primitive_item.h | 131 +++++-- .../plugins/world_editor/primitives_model.cpp | 245 ++++++------ .../plugins/world_editor/primitives_model.h | 46 ++- .../plugins/world_editor/primitives_view.cpp | 348 +++++++++++++----- .../plugins/world_editor/primitives_view.h | 34 +- .../world_editor/world_editor_actions.cpp | 191 +++++++++- .../world_editor/world_editor_actions.h | 100 ++++- .../world_editor/world_editor_window.cpp | 78 ++-- .../world_editor/world_editor_window.h | 8 +- .../world_editor/world_editor_window.ui | 12 +- 11 files changed, 1042 insertions(+), 347 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.cpp index 300a30631..e948f8b0f 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.cpp @@ -17,6 +17,9 @@ // 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 @@ -28,87 +31,160 @@ namespace WorldEditor { -BaseTreeItem::BaseTreeItem(BaseTreeItem *parent) +Node::Node() + : m_parent(0) { - m_parentItem = parent; - m_itemData << QIcon() << "" << "" << ""; } -BaseTreeItem::BaseTreeItem(const QList &data, BaseTreeItem *parent) +Node::~Node() { - m_parentItem = parent; - m_itemData = data; + if (m_parent) + m_parent->removeChildNode(this); + + qDeleteAll(m_children); + nlassert(m_children.isEmpty()); + m_data.clear(); } -BaseTreeItem::~BaseTreeItem() +void Node::prependChildNode(Node *node) { - qDeleteAll(m_childItems); + // 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 BaseTreeItem::appendChild(BaseTreeItem *item) +void Node::appendChildNode(Node *node) { - m_childItems.append(item); + // 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 BaseTreeItem::deleteChild(int row) +void Node::insertChildNodeAfter(Node *node, Node *after) { - delete m_childItems.takeAt(row); + // 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; } -BaseTreeItem *BaseTreeItem::child(int row) +void Node::removeChildNode(Node *node) { - return m_childItems.value(row); + nlassert(m_children.contains(node)); + nlassert(node->parent() == this); + + m_children.removeOne(node); + + node->m_parent = 0; } -int BaseTreeItem::childCount() const +Node *Node::child(int row) { - return m_childItems.count(); + return m_children.at(row); } -int BaseTreeItem::columnCount() const +int Node::childCount() const { - return m_itemData.count(); + return m_children.count(); } -QVariant BaseTreeItem::data(int column) const +QVariant Node::data(int key) const { - return m_itemData.value(column); + return m_data[key]; } -void BaseTreeItem::setData(int column, const QVariant &data) +void Node::setData(int key, const QVariant &data) { - m_itemData[column] = data; + m_data[key] = data; } -BaseTreeItem *BaseTreeItem::parent() +Node *Node::parent() { - return m_parentItem; + return m_parent; } -int BaseTreeItem::row() const +int Node::row() const { - if (m_parentItem) - return m_parentItem->m_childItems.indexOf(const_cast(this)); + if (m_parent) + return m_parent->m_children.indexOf(const_cast(this)); return 0; } -void BaseTreeItem::setModified(bool value) +Node::NodeType Node::type() const { - m_modified = value; + return BasicNodeType; } -bool BaseTreeItem::isModified() const +WorldEditNode::WorldEditNode(const QString &name) { - return m_modified; + setData(Qt::DisplayRole, name); + setData(Qt::DecorationRole, QIcon(Constants::ICON_WORLD_EDITOR)); } -PrimitiveItem::PrimitiveItem(NLLIGO::IPrimitive *primitive, BaseTreeItem *parent) - : BaseTreeItem(parent), - m_primitive(primitive) +WorldEditNode::~WorldEditNode() { - setData(1, QString(m_primitive->getName().c_str())); - setData(2, QString(m_primitive->getClassName().c_str())); +} + +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); @@ -125,43 +201,57 @@ PrimitiveItem::PrimitiveItem(NLLIGO::IPrimitive *primitive, BaseTreeItem *parent else icon = QIcon("./old_ico/folder_h.ico"); } - setData(0, icon); + setData(Qt::DecorationRole, icon); - setData(3, QString(className.c_str())); + //setData(3, QString(className.c_str())); } -/* -PrimitiveItem::PrimitiveItem(const PrimitiveItem &other) -{ -} -*/ -PrimitiveItem::~PrimitiveItem() + +PrimitiveNode::~PrimitiveNode() { } -NLLIGO::IPrimitive *PrimitiveItem::primitive() const +NLLIGO::IPrimitive *PrimitiveNode::primitive() const { return m_primitive; } -const NLLIGO::CPrimitiveClass *PrimitiveItem::primitiveClass() const +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; +} -RootPrimitiveItem::RootPrimitiveItem(const QString &name, NLLIGO::CPrimitives *primitives, BaseTreeItem *parent) - : PrimitiveItem(primitives->RootNode, parent), +RootPrimitiveNode::RootPrimitiveNode(const QString &name, NLLIGO::CPrimitives *primitives) + : PrimitiveNode(primitives->RootNode), m_primitives(primitives) { - setData(1, name); + setData(Qt::DisplayRole, name); } -/* -RootPrimitiveItem::RootPrimitiveItem(const RootPrimitiveItem &other) + +RootPrimitiveNode::~RootPrimitiveNode() { } -*/ -RootPrimitiveItem::~RootPrimitiveItem() + +NLLIGO::CPrimitives *RootPrimitiveNode::primitives() const +{ + return m_primitives; +} + +Node::NodeType RootPrimitiveNode::type() const { + return RootPrimitiveNodeType; } } /* namespace WorldEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h index 5d00e6c92..01c63962c 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h @@ -31,69 +31,144 @@ namespace WorldEditor { +class WorldEditNode; +class RootPrimitiveNode; +class LandscapeNode; +class PrimitiveNode; + /* -@class BaseTreeItem +@class Node @brief @details */ -class BaseTreeItem +class Node { public: - BaseTreeItem(BaseTreeItem *parent = 0); - BaseTreeItem(const QList &data, BaseTreeItem *parent = 0); - virtual ~BaseTreeItem(); - void appendChild(BaseTreeItem *child); - void deleteChild(int row); + 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); - BaseTreeItem *child(int row); + /// 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; - int columnCount() const; - QVariant data(int column) const; - void setData(int column, const QVariant &data); + + /// Return a row index this node. int row() const; - BaseTreeItem *parent(); - void setModified(bool value); - bool isModified() 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 m_children; + QHash m_data; +}; + +/* +@class WorldEditNode +@brief +@details +*/ +class WorldEditNode: public Node +{ +public: + WorldEditNode(const QString &name); + virtual ~WorldEditNode(); + + virtual NodeType type() const; private: +}; - bool m_modified; - QList m_childItems; - QList m_itemData; - BaseTreeItem *m_parentItem; +/* +@class LandscapeNode +@brief +@details +*/ +class LandscapeNode: public Node +{ +public: + LandscapeNode(const QString &name); + virtual ~LandscapeNode(); + + virtual NodeType type() const; + +private: }; /* -@class PrimitiveItem +@class PrimitiveNode @brief @details */ -class PrimitiveItem: public BaseTreeItem +class PrimitiveNode: public Node { public: - PrimitiveItem(NLLIGO::IPrimitive *primitive, BaseTreeItem *parent); - PrimitiveItem(const PrimitiveItem &other); - virtual ~PrimitiveItem(); + 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 PrimitivesItem +@class RootPrimitiveNode @brief @details */ -class RootPrimitiveItem: public PrimitiveItem +class RootPrimitiveNode: public PrimitiveNode { public: - RootPrimitiveItem(const QString &name, NLLIGO::CPrimitives *primitives, BaseTreeItem *parent); - RootPrimitiveItem(const RootPrimitiveItem &other); - virtual ~RootPrimitiveItem(); + RootPrimitiveNode(const QString &name, NLLIGO::CPrimitives *primitives); + virtual ~RootPrimitiveNode(); + + NLLIGO::CPrimitives *primitives() const; + + virtual NodeType type() const; private: NLLIGO::CPrimitives *m_primitives; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.cpp index 7a41822ab..bc8925175 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.cpp @@ -31,24 +31,26 @@ namespace WorldEditor { PrimitivesTreeModel::PrimitivesTreeModel(QObject *parent) - : QAbstractItemModel(parent) + : QAbstractItemModel(parent), + m_worldEditNode(0) { - QList rootData; - rootData << "Name" << "Class" << "Class"; - m_rootItem = new BaseTreeItem(rootData); + m_rootNode = new Node(); + m_rootNode->setData(Qt::DisplayRole, "Name"); } PrimitivesTreeModel::~PrimitivesTreeModel() { - delete m_rootItem; + delete m_rootNode; } int PrimitivesTreeModel::columnCount(const QModelIndex &parent) const { - if (parent.isValid()) - return static_cast(parent.internalPointer())->columnCount(); - else - return m_rootItem->columnCount(); + /* if (parent.isValid()) + return static_cast(parent.internalPointer())->columnCount(); + else + return m_rootItem->columnCount(); + */ + return 1; } QVariant PrimitivesTreeModel::data(const QModelIndex &index, int role) const @@ -56,20 +58,15 @@ QVariant PrimitivesTreeModel::data(const QModelIndex &index, int role) const if (!index.isValid()) return QVariant(); - BaseTreeItem *item = static_cast(index.internalPointer()); + Node *item = static_cast(index.internalPointer()); switch (role) { // case Qt::TextAlignmentRole: // return int(Qt::AlignLeft | Qt::AlignVCenter); case Qt::DisplayRole: - return item->data(index.column() + 1); + return item->data(Qt::DisplayRole); case Qt::DecorationRole: - { - if (index.column() == 0) - return qVariantFromValue(item->data(0)); - else - return QVariant(); - } + return item->data(Qt::DecorationRole); default: return QVariant(); } @@ -83,31 +80,30 @@ Qt::ItemFlags PrimitivesTreeModel::flags(const QModelIndex &index) const return Qt::ItemIsEnabled | Qt::ItemIsSelectable; } -QVariant PrimitivesTreeModel::headerData(int section, Qt::Orientation orientation, - int role) const +QVariant PrimitivesTreeModel::headerData(int section, Qt::Orientation orientation, int role) const { if (orientation == Qt::Horizontal && role == Qt::DisplayRole) - return m_rootItem->data(section); +// return m_rootNode->data(section); + return m_rootNode->data(Qt::DisplayRole); return QVariant(); } -QModelIndex PrimitivesTreeModel::index(int row, int column, const QModelIndex &parent) -const +QModelIndex PrimitivesTreeModel::index(int row, int column, const QModelIndex &parent) const { if (!hasIndex(row, column, parent)) return QModelIndex(); - BaseTreeItem *parentItem; + Node *parentNode; if (!parent.isValid()) - parentItem = m_rootItem; + parentNode = m_rootNode; else - parentItem = static_cast(parent.internalPointer()); + parentNode = static_cast(parent.internalPointer()); - BaseTreeItem *childItem = parentItem->child(row); - if (childItem) - return createIndex(row, column, childItem); + Node *childNode = parentNode->child(row); + if (childNode) + return createIndex(row, column, childNode); else return QModelIndex(); } @@ -117,161 +113,166 @@ QModelIndex PrimitivesTreeModel::parent(const QModelIndex &index) const if (!index.isValid()) return QModelIndex(); - BaseTreeItem *childItem = static_cast(index.internalPointer()); - BaseTreeItem *parentItem = childItem->parent(); + Node *childNode = static_cast(index.internalPointer()); + Node *parentNode = childNode->parent(); - if (parentItem == m_rootItem) + if (parentNode == m_rootNode) return QModelIndex(); - return createIndex(parentItem->row(), 0, parentItem); + return createIndex(parentNode->row(), 0, parentNode); } int PrimitivesTreeModel::rowCount(const QModelIndex &parent) const { - BaseTreeItem *parentItem; + Node *parentNode; if (parent.column() > 0) return 0; if (!parent.isValid()) - parentItem = m_rootItem; + parentNode = m_rootNode; else - parentItem = static_cast(parent.internalPointer()); + parentNode = static_cast(parent.internalPointer()); - return parentItem->childCount(); + return parentNode->childCount(); } -NLLIGO::IPrimitive *PrimitivesTreeModel::primitive(const QModelIndex &index) +Path PrimitivesTreeModel::pathFromIndex(const QModelIndex &index) { - NLLIGO::IPrimitive *prim = 0; - if (index.isValid()) + QModelIndex iter = index; + Path path; + while(iter.isValid()) { - PrimitiveItem *item = static_cast(index.internalPointer()); - prim = item->primitive(); + path.prepend(PathItem(iter.row(), iter.column())); + iter = iter.parent(); } - return prim; + return path; } -const NLLIGO::CPrimitiveClass *PrimitivesTreeModel::primitiveClass(const QModelIndex &index) +QModelIndex PrimitivesTreeModel::pathToIndex(const Path &path) { - if (index.isValid()) + QModelIndex iter; + for(int i = 0; i < path.size(); i++) { - NLLIGO::IPrimitive *prim = primitive(index); - return ligoConfig()->getPrimitiveClass(*prim); + iter = index(path[i].first, path[i].second, iter); } - return 0; + return iter; } -void PrimitivesTreeModel::loadPrimitive(const QString &fileName) +void PrimitivesTreeModel::createWorldEditNode(const QString &fileName) { - NLLIGO::CPrimitives *primitives = new NLLIGO::CPrimitives(); - - // set the primitive context - NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = primitives; - - NLLIGO::loadXmlPrimitiveFile(*primitives, fileName.toStdString(), *NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig); - - // unset the context - NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = NULL; - - addRootPrimitive(fileName, primitives); + beginResetModel(); + m_worldEditNode = new WorldEditNode(fileName); + m_rootNode->appendChildNode(m_worldEditNode); + endResetModel(); } -void PrimitivesTreeModel::newPrimitiveWithoutUndo(const QString &className, uint id, const QModelIndex &parent) +void PrimitivesTreeModel::deleteWorldEditNode() { - const NLLIGO::CPrimitiveClass *primClass = primitiveClass(parent); - float delta = 10; - - // TODO: Set the context - //CPrimitiveContext::instance().CurrentPrimitive = &_DataHierarchy[locator._LocateStack[0]].Primitives; - - NLLIGO::IPrimitive *newPrimitive = createPrimitive(className.toStdString().c_str(), className.toStdString().c_str() - , NLMISC::CVector(), delta, primClass->DynamicChildren[id].Parameters, primitive(parent)); - - // unset the context - //CPrimitiveContext::instance().CurrentPrimitive = NULL; - - if (newPrimitive != 0) + beginResetModel(); + if (m_worldEditNode != 0) { - scanPrimitive(newPrimitive, parent); + delete m_worldEditNode; + m_worldEditNode = 0; } + endResetModel(); } -void PrimitivesTreeModel::deletePrimitiveWithoutUndo(const QModelIndex &index) +Path PrimitivesTreeModel::createLandscapeNode(const QString &fileName) { - deletePrimitive(primitive(index)); - removeRows(index.row(), index.parent()); + 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()))); } -void PrimitivesTreeModel::addRootPrimitive(const QString &name, NLLIGO::CPrimitives *primitives) + +Path PrimitivesTreeModel::createRootPrimitiveNode(const QString &fileName, NLLIGO::CPrimitives *primitives) { - beginResetModel(); + if (m_worldEditNode == 0) + createWorldEditNode("NewWorldEdit"); - // Create root primitive - RootPrimitiveItem *newPrimitives = new RootPrimitiveItem(name, primitives, m_rootItem); - m_rootItem->appendChild(newPrimitives); + // Get position + int pos = m_worldEditNode->childCount(); - // Scan childs items and add in tree model + 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); - scanPrimitive(childPrim, newPrimitives); + createChildNodes(childPrim, rootPrimIndex); } - endResetModel(); + + return pathFromIndex(rootPrimIndex); } -void PrimitivesTreeModel::scanPrimitive(NLLIGO::IPrimitive *prim, const QModelIndex &parentIndex) +Path PrimitivesTreeModel::createPrimitiveNode(NLLIGO::IPrimitive *primitive, const Path &parent) { - PrimitiveItem *parent = static_cast(parentIndex.internalPointer()); + QModelIndex parentIndex = pathToIndex(parent); + Node *parentNode = static_cast(parentIndex.internalPointer()); + int pos = parentNode->childCount(); - // Add in tree model - beginInsertRows(parentIndex, parent->childCount(), parent->childCount()); - PrimitiveItem *newItem = new PrimitiveItem(prim, parent); - parent->appendChild(newItem); - endInsertRows(); + createChildNodes(primitive, parentIndex); - // Scan childs items and add in tree model - QModelIndex childIndex = index(parent->childCount() - 1, 0, parentIndex); - for (uint i = 0; i < prim->getNumChildren(); ++i) - { - NLLIGO::IPrimitive *childPrim; - prim->getChild(childPrim, i); - scanPrimitive(childPrim, childIndex); - } + return pathFromIndex(index(pos, 0, parentIndex)); } -void PrimitivesTreeModel::scanPrimitive(NLLIGO::IPrimitive *prim, BaseTreeItem *parent) +void PrimitivesTreeModel::deleteNode(const Path &path) { - // Add in tree model - PrimitiveItem *newItem = new PrimitiveItem(prim, parent); - parent->appendChild(newItem); + QModelIndex nodeIndex = pathToIndex(path); + QModelIndex parentIndex = nodeIndex.parent(); + Node *node = static_cast(nodeIndex.internalPointer()); - // Scan childs items and add in tree model - for (uint i = 0; i < prim->getNumChildren(); ++i) - { - NLLIGO::IPrimitive *childPrim; - prim->getChild(childPrim, i); - scanPrimitive(childPrim, newItem); - } + // Scan childs items and delete from the tree model + removeChildNodes(node, parentIndex); } -void PrimitivesTreeModel::removeRows(int position, const QModelIndex &parent) +void PrimitivesTreeModel::createChildNodes(NLLIGO::IPrimitive *primitive, const QModelIndex &parent) { - BaseTreeItem *item = static_cast(parent.internalPointer())->child(position); + Node *parentNode = static_cast(parent.internalPointer()); - // Delete all child items from tree model - while (item->childCount() != 0) - removeRows(0, parent.child(position, 0)); + int pos = parentNode->childCount(); - // Delete item - beginRemoveRows(parent, position, position); - static_cast(parent.internalPointer())->deleteChild(position); - endRemoveRows(); + // 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); + } } -NLLIGO::CLigoConfig *PrimitivesTreeModel::ligoConfig() const +void PrimitivesTreeModel::removeChildNodes(Node *node, const QModelIndex &parent) { - return NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig; + // 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 */ \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.h index ab4581a30..d2b6509ad 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.h @@ -31,9 +31,15 @@ namespace WorldEditor { +class Node; +class WorldEditNode; -class BaseTreeItem; -class PrimitiveItem; +typedef QPair 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 Path; /** @class PrimitivesTreeModel @@ -58,32 +64,34 @@ public: int rowCount(const QModelIndex &parent = QModelIndex()) const; int columnCount(const QModelIndex &parent = QModelIndex()) const; - // Get primitive - NLLIGO::IPrimitive *primitive(const QModelIndex &index); + /// 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); - // Get primitive class - const NLLIGO::CPrimitiveClass *primitiveClass(const QModelIndex &index); + QModelIndex pathToIndex(const Path &path); - // Load primitive from file - void loadPrimitive(const QString &fileName); + void createWorldEditNode(const QString &fileName); + void deleteWorldEditNode(); - // Create new primitive and add in tree model - void newPrimitiveWithoutUndo(const QString &className, uint id, const QModelIndex &parent); + /// Add new landscape node in tree model. + Path createLandscapeNode(const QString &fileName); - void deletePrimitiveWithoutUndo(const QModelIndex &index); + /// Add new root primitive node and all sub-primitives in the tree model. + Path createRootPrimitiveNode(const QString &fileName, NLLIGO::CPrimitives *primitives); - NLLIGO::CLigoConfig *ligoConfig() const; + /// Add new primitive node and all sub-primitives in the tree model. + Path createPrimitiveNode(NLLIGO::IPrimitive *primitive, const Path &parent); -private: - // Add root primitive in tree model and add all its sub-items. - void addRootPrimitive(const QString &name, NLLIGO::CPrimitives *primitives); + /// Delete node and all child nodes from the tree model + void deleteNode(const Path &path); - void scanPrimitive(NLLIGO::IPrimitive *prim, const QModelIndex &parentIndex); - void scanPrimitive(NLLIGO::IPrimitive *prim, BaseTreeItem *parent = 0); +private: + void createChildNodes(NLLIGO::IPrimitive *primitive, const QModelIndex &parent); - void removeRows(int position, const QModelIndex &parent); + void removeChildNodes(Node *node, const QModelIndex &parent); - BaseTreeItem *m_rootItem; + Node *m_rootNode; + WorldEditNode *m_worldEditNode; }; } /* namespace WorldEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.cpp index 0cc4e5e52..517dcee43 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.cpp @@ -16,8 +16,13 @@ // Project includes #include "primitives_view.h" -//#include "primitive_item.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 @@ -27,22 +32,56 @@ // Qt includes #include #include +#include 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 @@ -54,30 +93,116 @@ 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::deletePrimitives() +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(); - // TODO: use QPersistentModelIndex for deleting several items - m_primitivesTreeModel->deletePrimitiveWithoutUndo(indexList.first()); + selectionModel()->clearSelection(); + selectChildren(parentIndex); } -void PrimitivesView::addNewPrimitive(int value) +void PrimitivesView::deletePrimitives() { + nlassert(m_undoStack); + nlassert(m_primitivesTreeModel); + QModelIndexList indexList = selectionModel()->selectedRows(); +} - const NLLIGO::CPrimitiveClass *primClass = m_primitivesTreeModel->primitiveClass(indexList.first()); +void PrimitivesView::addNewPrimitiveByClass(int value) +{ + nlassert(m_undoStack); + nlassert(m_primitivesTreeModel); + + QModelIndexList indexList = selectionModel()->selectedRows(); + + PrimitiveNode *node = static_cast(indexList.first().internalPointer()); // Get class name - QString className = primClass->DynamicChildren[value].ClassName.c_str(); + QString className = node->primitiveClass()->DynamicChildren[value].ClassName.c_str(); - m_primitivesTreeModel->newPrimitiveWithoutUndo(className, value, indexList.first()); + m_undoStack->push(new AddPrimitiveByClassCommand(className, m_primitivesTreeModel->pathFromIndex(indexList.first()), + m_primitivesTreeModel)); } void PrimitivesView::generatePrimitives(int value) @@ -96,96 +221,153 @@ void PrimitivesView::contextMenuEvent(QContextMenuEvent *event) return; QMenu *popurMenu = new QMenu(this); - popurMenu->addAction(m_deleteAction); - popurMenu->addAction(m_selectChildrenAction); - popurMenu->addAction(m_helpAction); - popurMenu->addSeparator(); - popurMenu->addAction(m_showAction); - popurMenu->addAction(m_hideAction); - popurMenu->addSeparator(); - - QSignalMapper *addSignalMapper = new QSignalMapper(this); - QSignalMapper *generateSignalMapper = new QSignalMapper(this); - QSignalMapper *openSignalMapper = new QSignalMapper(this); - connect(addSignalMapper, SIGNAL(mapped(int)), this, SLOT(addNewPrimitive(int))); + + if (indexList.size() == 1) + { + Node *node = static_cast(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))); - if (indexList.size() == 1) + PrimitiveNode *node = static_cast(index.internalPointer()); + const NLLIGO::CPrimitiveClass *primClass = node->primitiveClass(); + + // What class is it ? + if (primClass && primClass->DynamicChildren.size()) { - const NLLIGO::CPrimitiveClass *primClass = m_primitivesTreeModel->primitiveClass(indexList.first()); + menu->addSeparator(); - // What class is it ? - if (primClass && primClass->DynamicChildren.size()) + // For each child, add a create method + for (size_t i = 0; i < primClass->DynamicChildren.size(); i++) { - popurMenu->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 class name + QString className = primClass->DynamicChildren[i].ClassName.c_str(); - // Get icon - QIcon icon(QString("./old_ico/%1.ico").arg(className)); + // Get icon + QIcon icon(QString("./old_ico/%1.ico").arg(className)); - // Create and add action in popur menu - QAction *action = popurMenu->addAction(icon, QString("Add %1").arg(className)); - addSignalMapper->setMapping(action, i); - connect(action, SIGNAL(triggered()), addSignalMapper, SLOT(map())); - } + // 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()) + // 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++) { - popurMenu->addSeparator(); + // Get class name + QString childName = primClass->GeneratedChildren[i].ClassName.c_str(); - // 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 = popurMenu->addAction(QString("Generate %1").arg(childName)); - generateSignalMapper->setMapping(action, i); - connect(generateSignalMapper, SIGNAL(triggered()), addSignalMapper, SLOT(map())); - } + // 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 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 ()); - } - } - } - */ } + /* + // What class is it ? + if (primClass) + { + // Look for files + std::vector filenames; - popurMenu->exec(event->globalPos()); - delete popurMenu; - delete addSignalMapper; - delete generateSignalMapper; - delete openSignalMapper; - event->accept(); + // 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 */ \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.h index b0381b5bf..67c3ffba0 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.h @@ -28,11 +28,15 @@ #include #include #include +#include -namespace WorldEditor +namespace LandscapeEditor { +class ZoneBuilderBase; +} -class BaseTreeItem; +namespace WorldEditor +{ class PrimitivesTreeModel; /** @@ -48,23 +52,47 @@ 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 addNewPrimitive(int value); + 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; }; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp index cae402d27..fb8299c23 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp @@ -1,5 +1,4 @@ // Object Viewer Qt - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited // Copyright (C) 2011 Dzmitry Kamiahin // // This program is free software: you can redistribute it and/or modify @@ -17,31 +16,211 @@ // 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 // NeL includes #include +#include +#include +#include +#include // Qt includes +#include namespace WorldEditor { -OpenLandscapeCommand::OpenLandscapeCommand(const QString &fileName, QUndoCommand *parent) +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(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_fileName(fileName), + m_model(model) { + setText("Load primitive file"); } -OpenLandscapeCommand::~OpenLandscapeCommand() +LoadRootPrimitiveCommand::~LoadRootPrimitiveCommand() { } -void OpenLandscapeCommand::undo() +void LoadRootPrimitiveCommand::undo() { + QModelIndex index = m_model->pathToIndex(m_rootPrimIndex); + + RootPrimitiveNode *node = static_cast(index.internalPointer()); + + delete node->primitives(); + + m_model->deleteNode(m_rootPrimIndex); } -void OpenLandscapeCommand::redo() +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(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(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 */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h index 5a1c1ea49..00951dd9e 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h @@ -1,5 +1,4 @@ // Object Viewer Qt - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited // Copyright (C) 2011 Dzmitry Kamiahin // // This program is free software: you can redistribute it and/or modify @@ -19,6 +18,7 @@ #define WORLD_EDITOR_ACTIONS_H // Project includes +#include "primitives_model.h" // NeL includes @@ -27,20 +27,110 @@ #include #include +namespace LandscapeEditor +{ +class ZoneBuilderBase; +} + namespace WorldEditor { -class OpenLandscapeCommand: public QUndoCommand +/** +@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: - OpenLandscapeCommand(const QString &fileName, QUndoCommand *parent = 0); - virtual ~OpenLandscapeCommand(); + AddPrimitiveByClassCommand(const QString &className, const Path &parentIndex, + PrimitivesTreeModel *model, QUndoCommand *parent = 0); + virtual ~AddPrimitiveByClassCommand(); virtual void undo(); virtual void redo(); private: - QString m_fileName; + const QString m_className; + Path m_parentIndex, m_newPrimIndex; + PrimitivesTreeModel *m_model; }; } /* namespace WorldEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp index fd9f9c755..132b52b70 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp @@ -1,5 +1,4 @@ // Object Viewer Qt - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited // Copyright (C) 2011 Dzmitry Kamiahin // // This program is free software: you can redistribute it and/or modify @@ -20,6 +19,8 @@ #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" @@ -28,17 +29,12 @@ // Lanscape Editor plugin #include "../landscape_editor/builder_zone_base.h" -//#include "../landscape_editor/project_settings_dialog.h" // NeL includes #include #include #include - -#include -#include -#include -#include +#include // Qt includes #include @@ -47,7 +43,6 @@ namespace WorldEditor { -QString _lastDir; WorldEditorWindow::WorldEditorWindow(QWidget *parent) : QMainWindow(parent), @@ -57,9 +52,9 @@ WorldEditorWindow::WorldEditorWindow(QWidget *parent) m_ui.setupUi(this); m_undoStack = new QUndoStack(this); - m_worldEditorScene = new WorldEditorScene(160, 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); @@ -78,12 +73,16 @@ WorldEditorWindow::WorldEditorWindow(QWidget *parent) 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(saveAllWorldEditFiles())); + connect(m_ui.saveWorldEditAction, SIGNAL(triggered()), this, SLOT(saveWorldEditFile())); } @@ -101,33 +100,64 @@ QUndoStack *WorldEditorWindow::undoStack() const void WorldEditorWindow::open() { - QStringList fileNames = QFileDialog::getOpenFileNames(this, - tr("Open NeL Ligo primitive file"), _lastDir, - tr("All NeL Ligo primitive files (*.primitive)")); + QString fileName = QFileDialog::getOpenFileName(this, + tr("Open NeL World Edit file"), m_lastDir, + tr("All NeL World Editor file (*.worldedit)")); setCursor(Qt::WaitCursor); - if (!fileNames.isEmpty()) + if (!fileName.isEmpty()) { - QStringList list = fileNames; - _lastDir = QFileInfo(list.front()).absolutePath(); - Q_FOREACH(QString fileName, fileNames) - { - loadPrimitive(fileName); - } + m_lastDir = QFileInfo(fileName).absolutePath(); + loadWorldEditFile(fileName); } setCursor(Qt::ArrowCursor); } -void WorldEditorWindow::loadPrimitive(const QString &fileName) +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() { - m_primitivesModel->loadPrimitive(fileName); } void WorldEditorWindow::newWorldEditFile() { + checkCurrentWorld(); + + m_undoStack->push(new CreateWorldCommand("NewWorldEdit", m_primitivesModel)); } -void WorldEditorWindow::saveAllWorldEditFiles() +void WorldEditorWindow::saveWorldEditFile() { } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h index 99768736b..2536bcc1c 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h @@ -1,5 +1,4 @@ // Object Viewer Qt - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited // Copyright (C) 2011 Dzmitry Kamiahin // // This program is free software: you can redistribute it and/or modify @@ -50,7 +49,7 @@ public Q_SLOTS: private Q_SLOTS: void newWorldEditFile(); - void saveAllWorldEditFiles(); + void saveWorldEditFile(); void openProjectSettings(); private: @@ -59,7 +58,10 @@ private: void readSettings(); void writeSettings(); - void loadPrimitive(const QString &fileName); + void loadWorldEditFile(const QString &fileName); + void checkCurrentWorld(); + + QString m_lastDir; PrimitivesTreeModel *m_primitivesModel; QUndoStack *m_undoStack; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui index 331dc34ff..80e4e5ace 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui @@ -20,7 +20,17 @@ - + + + QGraphicsView::RubberBandDrag + + + QGraphicsView::AnchorUnderMouse + + + QGraphicsView::AnchorUnderMouse + + From 51a8add985bd79988cd1ce3cdbdf600f4394edb4 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Sat, 6 Aug 2011 02:20:57 +0300 Subject: [PATCH 40/89] Fixed: #1301 Now works correctly with translucent tiles. --HG-- branch : gsoc2011-worldeditorqt --- .../landscape_editor/landscape_scene.cpp | 13 ++++++--- .../landscape_editor/landscape_scene_base.cpp | 11 ++++++-- .../landscape_editor/pixmap_database.cpp | 28 +++++++++++++++++-- .../landscape_editor/pixmap_database.h | 2 +- 4 files changed, 43 insertions(+), 11 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp index bdbe54f8c..bb2605b80 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp @@ -1,5 +1,4 @@ // Object Viewer Qt - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited // Copyright (C) 2011 Dzmitry Kamiahin // // This program is free software: you can redistribute it and/or modify @@ -100,14 +99,15 @@ QGraphicsItem *LandscapeScene::createItemZone(const LigoData &data, const ZonePo // Enable bilinear filtering item->setTransformationMode(Qt::SmoothTransformation); - NLLIGO::CZoneBankElement *zoneBankItem = m_zoneBuilder->getZoneBank().getElementByZoneName(data.zoneName); + 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 ((zoneBankItem->getSizeX() > 1) || (zoneBankItem->getSizeY() > 1)) + if ((sizeX > 1) || (sizeY > 1)) { - sint32 sizeX = zoneBankItem->getSizeX(), sizeY = zoneBankItem->getSizeY(); if (data.flip == 0) { switch (data.rot) @@ -165,6 +165,8 @@ QGraphicsItem *LandscapeScene::createItemZone(const LigoData &data, const ZonePo // for not full item zone item->setZValue(LAYER_ZONES); + item->setShapeMode(QGraphicsPixmapItem::BoundingRectShape); + return item; } @@ -178,6 +180,7 @@ QGraphicsItem *LandscapeScene::createItemEmptyZone(const ZonePosition &zonePos) // Get image from pixmap database QPixmap *pixmap = m_zoneBuilder->pixmapDatabase()->pixmap(QString(STRING_UNUSED)); + if (pixmap == 0) return 0; @@ -195,6 +198,8 @@ QGraphicsItem *LandscapeScene::createItemEmptyZone(const ZonePosition &zonePos) // for not full item zone item->setZValue(LAYER_EMPTY_ZONES); + item->setShapeMode(QGraphicsPixmapItem::BoundingRectShape); + return item; } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene_base.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene_base.cpp index 7946fffbc..473b1ad95 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene_base.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene_base.cpp @@ -97,14 +97,15 @@ QGraphicsItem *LandscapeSceneBase::createItemZone(const LigoData &data, const Zo // Enable bilinear filtering item->setTransformationMode(Qt::SmoothTransformation); - NLLIGO::CZoneBankElement *zoneBankItem = m_zoneBuilderBase->getZoneBank().getElementByZoneName(data.zoneName); + 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 ((zoneBankItem->getSizeX() > 1) || (zoneBankItem->getSizeY() > 1)) + if ((sizeX > 1) || (sizeY > 1)) { - sint32 sizeX = zoneBankItem->getSizeX(), sizeY = zoneBankItem->getSizeY(); if (data.flip == 0) { switch (data.rot) @@ -162,6 +163,8 @@ QGraphicsItem *LandscapeSceneBase::createItemZone(const LigoData &data, const Zo // for not full item zone item->setZValue(LAYER_ZONES); + item->setShapeMode(QGraphicsPixmapItem::BoundingRectShape); + return item; } @@ -192,6 +195,8 @@ QGraphicsItem *LandscapeSceneBase::createItemEmptyZone(const ZonePosition &zoneP // for not full item zone item->setZValue(LAYER_EMPTY_ZONES); + item->setShapeMode(QGraphicsPixmapItem::BoundingRectShape); + return item; } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.cpp index 52d8e04f3..d3dbd646d 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.cpp @@ -27,6 +27,7 @@ // Qt includes #include +#include #include #include #include @@ -35,12 +36,23 @@ namespace LandscapeEditor { PixmapDatabase::PixmapDatabase(int textureSize) - : m_textureSize(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(); } @@ -73,9 +85,19 @@ bool PixmapDatabase::loadPixmaps(const QString &zonePath, NLLIGO::CZoneBank &zon 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 - if (pixmap->width() != sizeX * m_textureSize) + 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; @@ -114,7 +136,7 @@ QStringList PixmapDatabase::listPixmaps() const QPixmap *PixmapDatabase::pixmap(const QString &zoneName) const { - QPixmap *result = 0; + QPixmap *result = m_errorPixmap; if (!m_pixmapMap.contains(zoneName)) nlwarning("QPixmap %s not found", zoneName.toStdString().c_str()); else diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.h index 85b0f180e..a9d4383ad 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.h @@ -1,5 +1,4 @@ // Object Viewer Qt - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited // Copyright (C) 2011 Dzmitry Kamiahin // // This program is free software: you can redistribute it and/or modify @@ -61,6 +60,7 @@ public: private: int m_textureSize; + QPixmap *m_errorPixmap; QMap m_pixmapMap; }; From e7118b39969c8d56f3c9c4dcfed0598d1f50a0a8 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Mon, 8 Aug 2011 21:57:28 +0300 Subject: [PATCH 41/89] Fixed: #1301 Smooth Panning and Zooming. --HG-- branch : gsoc2011-worldeditorqt --- .../landscape_editor_window.cpp | 4 +- .../landscape_editor/landscape_view.cpp | 157 +++++++++++++++--- .../plugins/landscape_editor/landscape_view.h | 12 +- 3 files changed, 149 insertions(+), 24 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp index a97dcf380..b3110a0e5 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp @@ -267,8 +267,8 @@ int LandscapeEditorWindow::createLandscape(const QString &fileName) 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()); + m_ui.graphicsView->setCenter(QPointF(zoneRegion->ligoZoneRegion().getMinX() * m_landscapeScene->cellSize(), + abs(zoneRegion->ligoZoneRegion().getMinY()) * m_landscapeScene->cellSize())); QListWidgetItem *item; if (fileName.isEmpty()) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp index c254fd65d..cad51d7cc 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp @@ -33,8 +33,7 @@ namespace LandscapeEditor LandscapeView::LandscapeView(QWidget *parent) : QGraphicsView(parent), m_visibleGrid(true), - m_visibleText(true), - m_moveMouse(false) + m_visibleText(false) { //setDragMode(ScrollHandDrag); setTransformationAnchor(AnchorUnderMouse); @@ -45,6 +44,9 @@ LandscapeView::LandscapeView(QWidget *parent) m_cellSize = 160; m_numSteps = 0; m_maxSteps = 20; + + //A modified version of centerOn(), handles special cases + setCenter(QPointF(500.0, 500.0)); } LandscapeView::~LandscapeView() @@ -70,25 +72,54 @@ void LandscapeView::setVisibleText(bool visible) 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) + /* 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);*/ + + //Get the position of the mouse before scaling, in scene coords + QPointF pointBeforeScale(mapToScene(event->pos())); + + //Get the original screen centerpoint + QPointF screenCenter = getCenter(); //CurrentCenterPoint; //(visRect.center()); + + //Scale the view ie. do the zoom + double scaleFactor = 1.15; //How fast we zoom + if(event->delta() > 0) { - // check max scale view - if (m_numSteps > m_maxSteps) - return; - ++m_numSteps; + //Zoom in + scale(scaleFactor, scaleFactor); } else { - // check min scale view - if (m_numSteps < -m_maxSteps) - return; - --m_numSteps; + //Zooming out + scale(1.0 / scaleFactor, 1.0 / scaleFactor); } - scale(factor, factor); - QGraphicsView::wheelEvent(event); + + //Get the position after scaling, in scene coords + QPointF pointAfterScale(mapToScene(event->pos())); + + //Get the offset of how the screen moved + QPointF offset = pointBeforeScale - pointAfterScale; + + //Adjust to the new center for correct zooming + QPointF newCenter = screenCenter + offset; + setCenter(newCenter); } void LandscapeView::mousePressEvent(QMouseEvent *event) @@ -96,24 +127,108 @@ void LandscapeView::mousePressEvent(QMouseEvent *event) QGraphicsView::mousePressEvent(event); if (event->button() != Qt::MiddleButton) return; - m_moveMouse = true; - QApplication::setOverrideCursor(Qt::ClosedHandCursor); + + //For panning the view + m_lastPanPoint = event->pos(); + setCursor(Qt::ClosedHandCursor); } void LandscapeView::mouseMoveEvent(QMouseEvent *event) { - if (m_moveMouse) - translate(0.001, 0.001); + if(!m_lastPanPoint.isNull()) + { + //Get how much we panned + QPointF delta = mapToScene(m_lastPanPoint) - mapToScene(event->pos()); + m_lastPanPoint = event->pos(); + + //Update the center ie. do the pan + setCenter(getCenter() + delta); + } + QGraphicsView::mouseMoveEvent(event); } void LandscapeView::mouseReleaseEvent(QMouseEvent *event) { + m_lastPanPoint = QPoint(); QApplication::restoreOverrideCursor(); - m_moveMouse = false; QGraphicsView::mouseReleaseEvent(event); } +void LandscapeView::resizeEvent(QResizeEvent *event) +{ + //Get the rectangle of the visible area in scene coords + QRectF visibleArea = mapToScene(rect()).boundingRect(); + setCenter(visibleArea.center()); + + //Call the subclass resize so the scrollbars are updated correctly + QGraphicsView::resizeEvent(event); +} + +void LandscapeView::setCenter(const QPointF ¢erPoint) +{ + //Get the rectangle of the visible area in scene coords + QRectF visibleArea = mapToScene(rect()).boundingRect(); + + //Get the scene area + QRectF sceneBounds = sceneRect(); + + double boundX = visibleArea.width() / 2.0; + double boundY = visibleArea.height() / 2.0; + double boundWidth = sceneBounds.width() - 2.0 * boundX; + double boundHeight = sceneBounds.height() - 2.0 * boundY; + + //The max boundary that the centerPoint can be to + QRectF bounds(boundX, boundY, boundWidth, boundHeight); + + if(bounds.contains(centerPoint)) + { + //We are within the bounds + m_currentCenterPoint = centerPoint; + } + else + { + //We need to clamp or use the center of the screen + if(visibleArea.contains(sceneBounds)) + { + //Use the center of scene ie. we can see the whole scene + m_currentCenterPoint = sceneBounds.center(); + } + else + { + m_currentCenterPoint = centerPoint; + + //We need to clamp the center. The centerPoint is too large + if (centerPoint.x() > bounds.x() + bounds.width()) + { + m_currentCenterPoint.setX(bounds.x() + bounds.width()); + } + else if(centerPoint.x() < bounds.x()) + { + m_currentCenterPoint.setX(bounds.x()); + } + + if(centerPoint.y() > bounds.y() + bounds.height()) + { + m_currentCenterPoint.setY(bounds.y() + bounds.height()); + } + else if(centerPoint.y() < bounds.y()) + { + m_currentCenterPoint.setY(bounds.y()); + } + + } + } + + //Update the scrollbars + centerOn(m_currentCenterPoint); +} + +QPointF LandscapeView::getCenter() const +{ + return m_currentCenterPoint; +} + void LandscapeView::drawForeground(QPainter *painter, const QRectF &rect) { QGraphicsView::drawForeground(painter, rect); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h index 20e7ee1bc..607afe60f 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h @@ -35,6 +35,10 @@ public: LandscapeView(QWidget *parent = 0); virtual ~LandscapeView(); + //Set the current centerpoint in the + void setCenter(const QPointF ¢erPoint); + QPointF getCenter() const; + bool isVisibleGrid() const; public Q_SLOTS: @@ -48,6 +52,7 @@ protected: virtual void mouseMoveEvent(QMouseEvent *event); virtual void mouseReleaseEvent(QMouseEvent *event); virtual void drawForeground(QPainter *painter, const QRectF &rect); + virtual void resizeEvent(QResizeEvent *event); void drawGrid(QPainter *painter, const QRectF &rect); void drawZoneNames(QPainter *painter, const QRectF &rect); @@ -56,7 +61,12 @@ private: bool m_visibleGrid, m_visibleText; int m_numSteps, m_maxSteps; int m_cellSize; - bool m_moveMouse; + + //Holds the current centerpoint for the view, used for panning and zooming + QPointF m_currentCenterPoint; + + //From panning the view + QPoint m_lastPanPoint; }; /* class LandscapeView */ } /* namespace LandscapeEditor */ From 9e3fd003d6877bbe5665adc041b64dbcd33da983 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Mon, 8 Aug 2011 21:59:09 +0300 Subject: [PATCH 42/89] Changed: #1302 Landscape scene works correctly in world editor plugin. --HG-- branch : gsoc2011-worldeditorqt --- .../landscape_editor/landscape_scene_base.cpp | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene_base.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene_base.cpp index 473b1ad95..3a8383ff1 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene_base.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene_base.cpp @@ -202,13 +202,16 @@ QGraphicsItem *LandscapeSceneBase::createItemEmptyZone(const ZonePosition &zoneP 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))) + QList listItems = items(QPointF(zonePos.x * m_cellSize + 10, abs(zonePos.y) * m_cellSize + 10), + Qt::IntersectsItemBoundingRect, Qt::AscendingOrder); + Q_FOREACH(QGraphicsItem *item, listItems) { - removeItem(item); - delete item; + if (dynamic_cast(item) != 0) + { + removeItem(item); + delete item; + return; + } } } @@ -246,6 +249,7 @@ void LandscapeSceneBase::delZoneRegion(const NLLIGO::CZoneRegion &zoneRegion) { for (sint32 j = zoneRegion.getMinY(); j <= zoneRegion.getMaxY(); ++j) { + deleteItemZone(ZonePosition(i, -j, -1)); } } @@ -314,10 +318,13 @@ void LandscapeSceneBase::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent) 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; + QList listItems = items(QPointF(posX * m_cellSize + 10, abs(posY) * m_cellSize + 10), + Qt::IntersectsItemBoundingRect, Qt::AscendingOrder); + Q_FOREACH(QGraphicsItem *item, listItems) + { + if (dynamic_cast(item) != 0) + return true; + } return false; } From 4c9614d841e516ffddf0789a6cec6d6422ed043c Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Mon, 8 Aug 2011 22:07:04 +0300 Subject: [PATCH 43/89] Changed: #1302 Added methods for keeping graphics data (QGraphicsItem and future the 3d_WorldEditor classes). --HG-- branch : gsoc2011-worldeditorqt --- .../src/plugins/world_editor/primitive_item.cpp | 10 ++++++++++ .../src/plugins/world_editor/primitive_item.h | 9 ++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.cpp index e948f8b0f..672bd2954 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.cpp @@ -132,6 +132,16 @@ void Node::setData(int key, const QVariant &data) m_data[key] = data; } +void Node::setGraphicsData(int key, void *pointerToData) +{ + m_graphicsData[key] = pointerToData; +} + +void *Node::graphicsData(int key) const +{ + return m_graphicsData[key]; +} + Node *Node::parent() { return m_parent; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h index 01c63962c..01c96c9d2 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h @@ -30,12 +30,14 @@ namespace WorldEditor { - class WorldEditNode; class RootPrimitiveNode; class LandscapeNode; class PrimitiveNode; +const int GRAPHICS_DATA_QT2D = 0; +const int GRAPHICS_DATA_NEL3D = 1; + /* @class Node @brief @@ -91,6 +93,10 @@ public: /// Return this node's custom data for the key key as a QVariant. QVariant data(int key) const; + void setGraphicsData(int key, void *pointerToData); + + void *graphicsData(int key) const; + /// Return a type this node. virtual NodeType type() const; @@ -100,6 +106,7 @@ private: Node *m_parent; QList m_children; QHash m_data; + QHash m_graphicsData; }; /* From b93f59ae1051721a2e15a3b01f68e47fe5b9fc5d Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Tue, 9 Aug 2011 23:31:14 +0300 Subject: [PATCH 44/89] Changed: #1302 Landscape scene works correctly in world editor plugin. Replaced dynamic_cast on more faster qgraphicsitem_cast. --HG-- branch : gsoc2011-worldeditorqt --- .../landscape_editor/landscape_scene_base.cpp | 26 +++++++++---------- .../landscape_editor/landscape_scene_base.h | 2 -- .../landscape_editor/landscape_view.cpp | 2 +- .../project_settings_dialog.h | 3 +-- .../project_settings_dialog.ui | 17 ++---------- 5 files changed, 17 insertions(+), 33 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene_base.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene_base.cpp index 3a8383ff1..9ae8d9bbd 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene_base.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene_base.cpp @@ -206,7 +206,7 @@ void LandscapeSceneBase::deleteItemZone(const ZonePosition &zonePos) Qt::IntersectsItemBoundingRect, Qt::AscendingOrder); Q_FOREACH(QGraphicsItem *item, listItems) { - if (dynamic_cast(item) != 0) + if (qgraphicsitem_cast(item) != 0) { removeItem(item); delete item; @@ -295,8 +295,6 @@ void LandscapeSceneBase::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) 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) @@ -310,20 +308,22 @@ void LandscapeSceneBase::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) QGraphicsScene::mouseMoveEvent(mouseEvent); } -void LandscapeSceneBase::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent) -{ - QGraphicsScene::mouseReleaseEvent(mouseEvent); - m_mouseButton = Qt::NoButton; -} - bool LandscapeSceneBase::checkUnderZone(const int posX, const int posY) { - QList listItems = items(QPointF(posX * m_cellSize + 10, abs(posY) * m_cellSize + 10), - Qt::IntersectsItemBoundingRect, Qt::AscendingOrder); + // TODO: Why crash program? + // QList listItems = items(QPointF(posX * m_cellSize + 10, abs(posY) * m_cellSize + 10), + // Qt::IntersectsItemBoundingRect, Qt::AscendingOrder); + + QList listItems = items(); + + QPointF point(posX, abs(posY)); Q_FOREACH(QGraphicsItem *item, listItems) { - if (dynamic_cast(item) != 0) - return true; + if (item->pos() == point) + { + if (qgraphicsitem_cast(item) != 0) + return true; + } } return false; } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene_base.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene_base.h index acfc0f9f7..b392b8a85 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene_base.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene_base.h @@ -64,7 +64,6 @@ 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); @@ -72,7 +71,6 @@ private: int m_cellSize; qreal m_mouseX, m_mouseY; sint32 m_posX, m_posY; - Qt::MouseButton m_mouseButton; ZoneBuilderBase *m_zoneBuilderBase; }; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp index cad51d7cc..6cc6b159e 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp @@ -151,7 +151,7 @@ void LandscapeView::mouseMoveEvent(QMouseEvent *event) void LandscapeView::mouseReleaseEvent(QMouseEvent *event) { m_lastPanPoint = QPoint(); - QApplication::restoreOverrideCursor(); + setCursor(Qt::ArrowCursor); QGraphicsView::mouseReleaseEvent(event); } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.h index e6b2b950a..abb93ab81 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.h @@ -20,14 +20,13 @@ // Project includes #include "ui_project_settings_dialog.h" -#include "landscape_editor_global.h" // Qt includes namespace LandscapeEditor { -class LANDSCAPE_EDITOR_EXPORT ProjectSettingsDialog: public QDialog +class ProjectSettingsDialog: public QDialog { Q_OBJECT diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.ui index 8be20c9aa..a666cb71c 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.ui +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.ui @@ -7,7 +7,7 @@ 0 0 419 - 93 + 67 @@ -38,20 +38,7 @@
- - - - Context: - - - contextComboBox - - - - - - - + Qt::Horizontal From d19feac70c0ee487ec1508d7b79660aef9900bbf Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Tue, 9 Aug 2011 23:56:26 +0300 Subject: [PATCH 45/89] Changed: #1302 Added additional visual elements (Point, Path, Zone) in 2d render without undo/redo operations(move, rotate, scale). --HG-- branch : gsoc2011-worldeditorqt --- .../src/plugins/world_editor/CMakeLists.txt | 3 + .../plugins/world_editor/primitives_model.h | 2 + .../plugins/world_editor/primitives_view.cpp | 8 +- .../plugins/world_editor/primitives_view.h | 4 +- .../world_editor/project_settings_dialog.cpp | 59 ++ .../world_editor/project_settings_dialog.h | 48 ++ .../world_editor/project_settings_dialog.ui | 103 +++ .../world_editor/world_editor_actions.cpp | 97 ++- .../world_editor/world_editor_actions.h | 8 +- .../world_editor/world_editor_constants.h | 1 + .../world_editor/world_editor_misc.cpp | 5 + .../plugins/world_editor/world_editor_misc.h | 2 + .../world_editor/world_editor_scene.cpp | 292 +++++++- .../plugins/world_editor/world_editor_scene.h | 46 +- .../world_editor/world_editor_scene_item.cpp | 649 ++++++++++++++++++ .../world_editor/world_editor_scene_item.h | 237 +++++++ .../world_editor/world_editor_window.cpp | 99 ++- .../world_editor/world_editor_window.h | 10 + .../world_editor/world_editor_window.ui | 59 +- 19 files changed, 1687 insertions(+), 45 deletions(-) create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/project_settings_dialog.cpp create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/project_settings_dialog.h create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/project_settings_dialog.ui create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.cpp create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/CMakeLists.txt index 1e41175bd..07d7fa5d1 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/CMakeLists.txt +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/CMakeLists.txt @@ -12,11 +12,14 @@ SET(OVQT_EXT_SYS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/../../extension_system/iplugin. SET(OVQT_PLUGIN_WORLD_EDITOR_HDR world_editor_plugin.h world_editor_window.h world_editor_scene.h + world_editor_scene_item.h primitives_model.h primitives_view.h + project_settings_dialog.h ) SET(OVQT_PLUGIN_WORLD_EDITOR_UIS world_editor_window.ui + project_settings_dialog.ui ) SET(OVQT_PLUGIN_WORLD_EDITOR_RCS world_editor.qrc) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.h index d2b6509ad..7f9a90aa7 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.h @@ -68,6 +68,8 @@ public: /// @Path is a list of [row,column] pairs showing us the way through the model. Path pathFromIndex(const QModelIndex &index); + //Path pathFromNode(Node *index); + QModelIndex pathToIndex(const Path &path); void createWorldEditNode(const QString &fileName); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.cpp index 517dcee43..f324da9b9 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.cpp @@ -40,6 +40,7 @@ namespace WorldEditor PrimitivesView::PrimitivesView(QWidget *parent) : QTreeView(parent), m_undoStack(0), + m_worldEditorScene(0), m_zoneBuilder(0), m_primitivesTreeModel(0) { @@ -103,6 +104,11 @@ void PrimitivesView::setZoneBuilder(LandscapeEditor::ZoneBuilderBase *zoneBuilde m_zoneBuilder = zoneBuilder; } +void PrimitivesView::setWorldScene(WorldEditorScene *worldEditorScene) +{ + m_worldEditorScene = worldEditorScene; +} + void PrimitivesView::setModel(PrimitivesTreeModel *model) { QTreeView::setModel(model); @@ -127,7 +133,7 @@ void PrimitivesView::loadRootPrimitive() Q_FOREACH(QString fileName, fileNames) { m_lastDir = QFileInfo(fileName).absolutePath(); - m_undoStack->push(new LoadRootPrimitiveCommand(fileName, m_primitivesTreeModel)); + m_undoStack->push(new LoadRootPrimitiveCommand(fileName, m_worldEditorScene, m_primitivesTreeModel)); } if (fileNames.count() > 1) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.h index 67c3ffba0..18785b909 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.h @@ -27,7 +27,6 @@ #include #include #include -#include #include namespace LandscapeEditor @@ -38,6 +37,7 @@ class ZoneBuilderBase; namespace WorldEditor { class PrimitivesTreeModel; +class WorldEditorScene; /** @class PrimitivesView @@ -54,6 +54,7 @@ public: void setUndoStack(QUndoStack *undoStack); void setZoneBuilder(LandscapeEditor::ZoneBuilderBase *zoneBuilder); + void setWorldScene(WorldEditorScene *worldEditorScene); virtual void setModel(PrimitivesTreeModel *model); private Q_SLOTS: @@ -92,6 +93,7 @@ private: QAction *m_hideAction; QUndoStack *m_undoStack; + WorldEditorScene *m_worldEditorScene; LandscapeEditor::ZoneBuilderBase *m_zoneBuilder; PrimitivesTreeModel *m_primitivesTreeModel; }; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/project_settings_dialog.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/project_settings_dialog.cpp new file mode 100644 index 000000000..28654864c --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/project_settings_dialog.cpp @@ -0,0 +1,59 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +// Project includes +#include "project_settings_dialog.h" + +#include "../core/icore.h" +#include "../core/core_constants.h" + +// NeL includes +#include + +// Qt includes +#include +#include +#include + +namespace WorldEditor +{ + +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 WorldEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/project_settings_dialog.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/project_settings_dialog.h new file mode 100644 index 000000000..b9a54b9ed --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/project_settings_dialog.h @@ -0,0 +1,48 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +#ifndef PROJECT_SETTINGS_DIALOG_WE_H +#define PROJECT_SETTINGS_DIALOG_WE_H + +// Project includes +#include "ui_project_settings_dialog.h" + +// Qt includes + +namespace WorldEditor +{ + +class 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 WorldEditor */ + +#endif // PROJECT_SETTINGS_DIALOG_WE_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/project_settings_dialog.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/project_settings_dialog.ui new file mode 100644 index 000000000..6904a57a2 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/project_settings_dialog.ui @@ -0,0 +1,103 @@ + + + ProjectSettingsDialog + + + + 0 + 0 + 419 + 93 + + + + Project settings + + + + :/icons/ic_nel_landscape_settings.png:/icons/ic_nel_landscape_settings.png + + + + + + Data directory: + + + pathLineEdit + + + + + + + + + + ... + + + + + + + Context: + + + contextComboBox + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + + + buttonBox + accepted() + ProjectSettingsDialog + accept() + + + 257 + 83 + + + 157 + 274 + + + + + buttonBox + rejected() + ProjectSettingsDialog + reject() + + + 325 + 83 + + + 286 + 274 + + + + + diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp index fb8299c23..a654e8f31 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp @@ -18,6 +18,8 @@ #include "world_editor_actions.h" #include "world_editor_misc.h" #include "primitive_item.h" +#include "world_editor_scene.h" +#include "world_editor_scene_item.h" // Lanscape Editor plugin #include "../landscape_editor/builder_zone_base.h" @@ -30,6 +32,7 @@ #include #include #include +#include #include // Qt includes @@ -38,6 +41,92 @@ namespace WorldEditor { +void addNewGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *model, WorldEditorScene *scene) +{ + PrimitiveNode *node = static_cast(primIndex.internalPointer()); + + float cellSize = Utils::ligoConfig()->CellSize; + if (node != 0) + { + NLLIGO::IPrimitive *primitive = node->primitive(); + NLLIGO::CPrimVector *vec = 0; + QGraphicsItem *item; + switch (node->primitiveClass()->Type) + { + case NLLIGO::CPrimitiveClass::Point: + { + vec = primitive->getPrimVector(); + item = scene->addWorldItemPoint(QPointF(vec->x, -vec->y + cellSize), 0); + break; + } + case NLLIGO::CPrimitiveClass::Path: + { + QPolygonF polygon; + vec = primitive->getPrimVector(); + int sizeVec = primitive->getNumVector(); + + for (int i = 0; i < sizeVec; ++i) + { + polygon << QPointF(vec->x, -vec->y + cellSize); + ++vec; + } + + item = scene->addWorldItemPath(polygon); + break; + } + case NLLIGO::CPrimitiveClass::Zone: + { + QPolygonF polygon; + vec = primitive->getPrimVector(); + int sizeVec = primitive->getNumVector(); + + for (int i = 0; i < sizeVec; ++i) + { + polygon << QPointF(vec->x, -vec->y + cellSize); + ++vec; + } + item = scene->addWorldItemZone(polygon); + break; + } + } + + node->setGraphicsData(GRAPHICS_DATA_QT2D, item); + } + + int count = model->rowCount(primIndex); + for (int i = 0; i < count; ++i) + { + addNewGraphicsItems(primIndex.child(i, 0), model, scene); + } +} + +void removeGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *model, WorldEditorScene *scene) +{ + PrimitiveNode *node = static_cast(primIndex.internalPointer()); + + if (node != 0) + { + switch (node->primitiveClass()->Type) + { + case NLLIGO::CPrimitiveClass::Point: + case NLLIGO::CPrimitiveClass::Path: + case NLLIGO::CPrimitiveClass::Zone: + { + QGraphicsItem *item = static_cast(node->graphicsData(GRAPHICS_DATA_QT2D)); + if (item != 0) + delete item; + break; + } + } + } + + int count = model->rowCount(primIndex); + for (int i = 0; i < count; ++i) + { + removeGraphicsItems(primIndex.child(i, 0), model, scene); + } +} + CreateWorldCommand::CreateWorldCommand(const QString &fileName, PrimitivesTreeModel *model, QUndoCommand *parent) : QUndoCommand(parent), m_fileName(fileName), @@ -121,9 +210,11 @@ void CreateRootPrimitiveCommand::redo() } -LoadRootPrimitiveCommand::LoadRootPrimitiveCommand(const QString &fileName, PrimitivesTreeModel *model, QUndoCommand *parent) +LoadRootPrimitiveCommand::LoadRootPrimitiveCommand(const QString &fileName, WorldEditorScene *scene, + PrimitivesTreeModel *model, QUndoCommand *parent) : QUndoCommand(parent), m_fileName(fileName), + m_scene(scene), m_model(model) { setText("Load primitive file"); @@ -137,6 +228,8 @@ void LoadRootPrimitiveCommand::undo() { QModelIndex index = m_model->pathToIndex(m_rootPrimIndex); + removeGraphicsItems(index, m_model, m_scene); + RootPrimitiveNode *node = static_cast(index.internalPointer()); delete node->primitives(); @@ -167,6 +260,8 @@ void LoadRootPrimitiveCommand::redo() } m_rootPrimIndex = m_model->createRootPrimitiveNode(m_fileName, primitives); + + addNewGraphicsItems(m_model->pathToIndex(m_rootPrimIndex), m_model, m_scene); } AddPrimitiveByClassCommand::AddPrimitiveByClassCommand(const QString &className, const Path &parentIndex, diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h index 00951dd9e..7393861b0 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h @@ -34,6 +34,10 @@ class ZoneBuilderBase; namespace WorldEditor { +class WorldEditorScene; + +void addNewGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *model, WorldEditorScene *scene); +void removeGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *model, WorldEditorScene *scene); /** @class CreateWorldCommand @@ -100,7 +104,8 @@ private: class LoadRootPrimitiveCommand: public QUndoCommand { public: - LoadRootPrimitiveCommand(const QString &fileName, PrimitivesTreeModel *model, QUndoCommand *parent = 0); + LoadRootPrimitiveCommand(const QString &fileName, WorldEditorScene *scene, + PrimitivesTreeModel *model, QUndoCommand *parent = 0); virtual ~LoadRootPrimitiveCommand(); virtual void undo(); @@ -109,6 +114,7 @@ private: Path m_rootPrimIndex; const QString m_fileName; + WorldEditorScene *const m_scene; PrimitivesTreeModel *const m_model; }; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_constants.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_constants.h index cb1abf21e..5c1d32908 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_constants.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_constants.h @@ -30,6 +30,7 @@ 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 WORLD_EDITOR_USE_OPENGL = "WorldEditorUseOpenGL"; const char *const ZONE_SNAPSHOT_RES = "WorldEditorZoneSnapshotRes"; const char *const PRIMITIVE_CLASS_FILENAME = "WorldEditorPrimitiveClassFilename"; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_misc.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_misc.cpp index e06332deb..1f77ee63d 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_misc.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_misc.cpp @@ -688,5 +688,10 @@ bool recursiveUpdateDefaultValues(NLLIGO::IPrimitive *primitive) return modified; } +NLLIGO::CLigoConfig *ligoConfig() +{ + return NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig; +} + } /* namespace Utils */ } /* namespace WorldEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_misc.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_misc.h index ea6a59f58..2e7fc93b1 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_misc.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_misc.h @@ -74,6 +74,8 @@ bool updateDefaultValues(NLLIGO::IPrimitive *primitive); bool recursiveUpdateDefaultValues(NLLIGO::IPrimitive *primitive); +NLLIGO::CLigoConfig *ligoConfig(); + } /* namespace Utils */ } /* namespace WorldEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp index 2c4c41065..fd2d85a24 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp @@ -30,42 +30,304 @@ namespace WorldEditor { WorldEditorScene::WorldEditorScene(int sizeCell, QObject *parent) - : LandscapeEditor::LandscapeSceneBase(sizeCell, parent) + : LandscapeEditor::LandscapeSceneBase(sizeCell, parent), + m_editedSelectedItems(false), + m_lastPickedPrimitive(0), + m_mode(SelectMode), + m_editMode(false) { + setItemIndexMethod(NoIndex); + + m_pen.setColor(QColor(50, 255, 155)); + m_pen.setWidth(0); + + m_brush.setColor(QColor(50, 255, 155, 80)); + m_brush.setStyle(Qt::SolidPattern); } WorldEditorScene::~WorldEditorScene() { } -/* -void LandscapeSceneBase::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) + +QGraphicsItem *WorldEditorScene::addWorldItemPoint(const QPointF &point, const float angle) +{ + WorldItemPoint *item = new WorldItemPoint(point, angle); + addItem(item); + return item; +} + +QGraphicsItem *WorldEditorScene::addWorldItemPath(const QPolygonF &polyline) +{ + WorldItemPath *item = new WorldItemPath(polyline); + addItem(item); + return item; +} + +QGraphicsItem *WorldEditorScene::addWorldItemZone(const QPolygonF &polygon) +{ + WorldItemZone *item = new WorldItemZone(polygon); + addItem(item); + return item; +} + +void WorldEditorScene::setModeEdit(WorldEditorScene::ModeEdit mode) { - QGraphicsScene::mousePressEvent(mouseEvent); + if (mode == WorldEditorScene::SelectMode) + m_editedSelectedItems = false; + + m_selectionArea = QRectF(); + + m_mode = mode; +} + +WorldEditorScene::ModeEdit WorldEditorScene::editMode() const +{ + return m_mode; +} + +bool WorldEditorScene::isEnabledEditPoint() const +{ + return m_editMode; +} + +void WorldEditorScene::setEnabledEditPoint(bool enabled) +{ + m_editMode = enabled; +} + +void WorldEditorScene::drawForeground(QPainter *painter, const QRectF &rect) +{ + QGraphicsScene::drawForeground(painter, rect); + + if ((m_selectionArea.left() != 0) && (m_selectionArea.right() != 0)) + { + painter->setPen(m_pen); + painter->setBrush(m_brush); + painter->drawRect(m_selectionArea); + } +} + +void WorldEditorScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) +{ + LandscapeEditor::LandscapeSceneBase::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(); + if (mouseEvent->button() != Qt::LeftButton) + return; + +// if ((!m_editedSelectedItems) && (m_mode != WorldEditorScene::SelectMode)) + if ((!m_editedSelectedItems && m_selectedItems.isEmpty()) || + (!calcBoundingShape(m_selectedItems).contains(mouseEvent->scenePos()))) + { + updatePickSelection(mouseEvent->scenePos()); + m_firstSelection = true; + } + + m_editedSelectedItems = false; + + switch (m_mode) + { + case WorldEditorScene::SelectMode: + { + m_selectionArea.setTopLeft(mouseEvent->scenePos()); + break; + } + case WorldEditorScene::MoveMode: + { + break; + } + case WorldEditorScene::RotateMode: + break; + case WorldEditorScene::ScaleMode: + break; + case WorldEditorScene::TurnMode: + break; + case WorldEditorScene::RadiusMode: + break; + }; + +// if (m_selectedItems.isEmpty()) +// m_selectionArea.setTopLeft(mouseEvent->scenePos()); } -void LandscapeSceneBase::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) +void WorldEditorScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) { - m_mouseX = mouseEvent->scenePos().x(); - m_mouseY = mouseEvent->scenePos().y() - m_cellSize; + if (QApplication::mouseButtons() == Qt::LeftButton) + { + + QPointF offset(mouseEvent->scenePos() - mouseEvent->lastScenePos()); + + m_selectionArea.setBottomRight(mouseEvent->scenePos()); + + switch (m_mode) + { + case WorldEditorScene::SelectMode: + break; + case WorldEditorScene::MoveMode: + { + Q_FOREACH(QGraphicsItem *item, m_selectedItems) + { + qgraphicsitem_cast(item)->moveOn(offset); + } + break; + } + case WorldEditorScene::RotateMode: + { + QRectF pivot = calcBoundingRect(m_selectedItems); + + // Caluculate angle between two line + QLineF firstLine(pivot.center(), mouseEvent->lastScenePos()); + QLineF secondLine(pivot.center(), mouseEvent->scenePos()); + qreal angle = secondLine.angleTo(firstLine); - m_posX = sint32(floor(m_mouseX / m_cellSize)); - m_posY = sint32(-floor(m_mouseY / m_cellSize)); + Q_FOREACH(QGraphicsItem *item, m_selectedItems) + { + qgraphicsitem_cast(item)->rotateOn(pivot.center(), angle); + } + break; + } + case WorldEditorScene::ScaleMode: + { + // float scale = (_SelectionMin.x - _SelectionMax.x + _SelectionMax.y - _SelectionMin.y) * SCALE_PER_PIXEL + 1.f; + // moveAction->setScale (std::max (0.001f, scale), _MainFrame->getTransformMode ()==CMainFrame::Scale, radius); + // TODO: perfomance + QRectF pivot = calcBoundingRect(m_selectedItems); + Q_FOREACH(QGraphicsItem *item, m_selectedItems) + { + qgraphicsitem_cast(item)->scaleOn(pivot.center(), offset); + } + break; + } + case WorldEditorScene::TurnMode: + break; + case WorldEditorScene::RadiusMode: + break; + }; + + if ((editMode() != WorldEditorScene::SelectMode) && (!m_selectedItems.isEmpty())) + m_editedSelectedItems = true; + else + m_editedSelectedItems = false; + + update(); + } + /*m_mouseX = mouseEvent->scenePos().x(); + m_mouseY = mouseEvent->scenePos().y() - m_cellSize; + */ QGraphicsScene::mouseMoveEvent(mouseEvent); } -void LandscapeSceneBase::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent) +void WorldEditorScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent) { + if (mouseEvent->button() != Qt::LeftButton) + return; + + if ((m_selectionArea.left() != 0) && (m_selectionArea.right() != 0)) + { + QList listItems; + + // Clear selection + updateSelectedItems(false); + m_selectedItems.clear(); + + if (m_selectionArea.left() < m_selectionArea.right()) + { + listItems = items(m_selectionArea, Qt::IntersectsItemShape, + Qt::AscendingOrder); + } + else + { + listItems = items(m_selectionArea, Qt::ContainsItemShape, + Qt::AscendingOrder); + } + + Q_FOREACH(QGraphicsItem *item, listItems) + { + if (qgraphicsitem_cast(item) == 0) + continue; + + m_selectedItems.push_back(item); + } + updateSelectedItems(true); + m_selectionArea = QRectF(); + update(); + } + else + { + if ((!m_editedSelectedItems) && (!m_firstSelection)) + updatePickSelection(mouseEvent->scenePos()); + else + m_firstSelection = false; + } +// Huck for standart selection model +// clearSelection(); +// updateSelectedItems(true); + QGraphicsScene::mouseReleaseEvent(mouseEvent); - m_mouseButton = Qt::NoButton; } -*/ + +QRectF WorldEditorScene::calcBoundingRect(const QList &listItems) +{ + QRectF rect; + Q_FOREACH(QGraphicsItem *item, listItems) + { + QRectF itemRect = item->boundingRect(); + rect = rect.united(itemRect.translated(item->pos())); + } + return rect; +} + +QPainterPath WorldEditorScene::calcBoundingShape(const QList &listItems) +{ + QPainterPath painterPath; + Q_FOREACH(QGraphicsItem *item, listItems) + { + QPainterPath itemPath = item->shape(); + painterPath = painterPath.united(itemPath.translated(item->pos())); + } + return painterPath; +} + +void WorldEditorScene::updateSelectedItems(bool value) +{ + Q_FOREACH(QGraphicsItem *item, m_selectedItems) + { + if (value) + { + item->setFlag(QGraphicsItem::ItemIsSelectable); + //item->setZValue(SELECTED_LAYER); + } + else + { + item->setFlag(QGraphicsItem::ItemIsSelectable, false); + //item->setZValue(UNSELECTED_LAYER); + } + item->setSelected(value); + } +} + +void WorldEditorScene::updatePickSelection(const QPointF &point) +{ + //clearSelection(); + updateSelectedItems(false); + m_selectedItems.clear(); + + QList listItems = items(point, Qt::ContainsItemShape, + Qt::AscendingOrder); + if (!listItems.isEmpty()) + { + // Next primitives + m_lastPickedPrimitive++; + m_lastPickedPrimitive %= listItems.size(); + QGraphicsItem *selectedItem = listItems.at(m_lastPickedPrimitive); + if (qgraphicsitem_cast(selectedItem) != 0) + m_selectedItems.push_back(selectedItem); + + updateSelectedItems(true); + } +} } /* namespace WorldEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h index 84dba333c..36f27b9b4 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h @@ -19,6 +19,7 @@ // Project includes #include "world_editor_global.h" +#include "world_editor_scene_item.h" #include "../landscape_editor/landscape_scene_base.h" @@ -39,17 +40,56 @@ class WORLD_EDITOR_EXPORT WorldEditorScene : public LandscapeEditor::LandscapeSc Q_OBJECT public: + enum ModeEdit + { + SelectMode = 0, + MoveMode, + RotateMode, + ScaleMode, + TurnMode, + RadiusMode + }; + WorldEditorScene(int sizeCell = 160, QObject *parent = 0); virtual ~WorldEditorScene(); + QGraphicsItem *addWorldItemPoint(const QPointF &point, const float angle); + QGraphicsItem *addWorldItemPath(const QPolygonF &polyline); + QGraphicsItem *addWorldItemZone(const QPolygonF &polygon); + + void setModeEdit(WorldEditorScene::ModeEdit mode); + WorldEditorScene::ModeEdit editMode() const; + + bool isEnabledEditPoint() const; + public Q_SLOTS: + void setEnabledEditPoint(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); + + virtual void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent); + virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent); private: + + QRectF calcBoundingRect(const QList &listItems); + QPainterPath calcBoundingShape(const QList &listItems); + void updateSelectedItems(bool value); + + void updatePickSelection(const QPointF &point); + + QPen m_pen; + QBrush m_brush; + + QRectF m_selectionArea; + qreal m_firstPickX, m_firstPickY; + QList m_selectedItems; + bool m_editedSelectedItems, m_firstSelection; + uint m_lastPickedPrimitive; + ModeEdit m_mode; + bool m_editMode; }; } /* namespace WorldEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.cpp new file mode 100644 index 000000000..f88c95b9a --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.cpp @@ -0,0 +1,649 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +// Project includes +#include "world_editor_scene_item.h" + +// NeL includes +#include + +// Qt includes +#include +#include +#include +#include +#include +#include + +namespace WorldEditor +{ + +static QPainterPath qt_graphicsItem_shapeFromPath(const QPainterPath &path, const QPen &pen) +{ + // We unfortunately need this hack as QPainterPathStroker will set a width of 1.0 + // if we pass a value of 0.0 to QPainterPathStroker::setWidth() + const qreal penWidthZero = qreal(0.00000001); + + if (path == QPainterPath()) + return path; + QPainterPathStroker ps; + ps.setCapStyle(pen.capStyle()); + if (pen.widthF() <= 0.0) + ps.setWidth(penWidthZero); + else + ps.setWidth(pen.widthF()); + ps.setJoinStyle(pen.joinStyle()); + ps.setMiterLimit(pen.miterLimit()); + QPainterPath p = ps.createStroke(path); + p.addPath(path); + return p; +} +/* +GraphicsItemNode::GraphicsItemNode(GraphicsItemZone *itemZone, QGraphicsItem *parent) + : QGraphicsObject(parent) +{ + m_itemZone = itemZone; + m_color = QColor(12, 150, 215); + //setFlag(ItemIgnoresTransformations, true); + //setFlag(ItemClipsToShape); + + QPropertyAnimation *animation = new QPropertyAnimation(this, "colorNode"); + animation->setDuration(3000); + animation->setStartValue(QColor(10, 0, 50)); + animation->setKeyValueAt(0.5, QColor(155, 255, 0)); + animation->setEndValue(QColor(10, 0, 50)); + animation->setLoopCount(2000); + animation->setEasingCurve(QEasingCurve::OutInExpo); + animation->start(); + + setFlag(ItemIsSelectable); + setFlag(ItemIsMovable); + setFlag(ItemSendsScenePositionChanges); + m_type = EdgeType; + + setAcceptedMouseButtons(Qt::LeftButton | Qt::RightButton); + setZValue(10000000); +} + +GraphicsItemNode::~GraphicsItemNode() +{ +} + +void GraphicsItemNode::setColorNode(const QColor &color) +{ + m_color = color; + update(); +} + +void GraphicsItemNode::setNodeType(NodeType nodeType) +{ + m_type = nodeType; + if (m_type == EdgeType) + { + setFlag(ItemIsSelectable); + setFlag(ItemIsMovable); + setFlag(ItemSendsScenePositionChanges); + setAcceptedMouseButtons(Qt::LeftButton | Qt::RightButton); + setZValue(10000); + } + else if (m_type == MiddleType) + { + setFlag(ItemIsSelectable, false); + setFlag(ItemIsMovable, false); + setFlag(ItemSendsScenePositionChanges, false); + setAcceptedMouseButtons(Qt::LeftButton); + setZValue(10001); + } + update(); +} + +QRectF GraphicsItemNode::boundingRect() const +{ + return QRectF(QPointF(0, 0), QSizeF(20, 20)); +} + +void GraphicsItemNode::paint(QPainter *painter, + const QStyleOptionGraphicsItem *option, + QWidget *) +{ + // Here comes the magic: + //painter->setClipRect(option->exposedRect); + + painter->setPen(Qt::NoPen); + + if (m_type == EdgeType) + { + painter->setBrush(QColor(255, 0, 0)); + } + else if (m_type == MiddleType) + { + painter->setBrush(QColor(0, 0, 255)); + } + if (option->state & QStyle::State_Selected) + { + painter->setBrush(QColor(0, 255, 0)); + } + + painter->drawRect(2, 2, 18, 18); +} + +QVariant GraphicsItemNode::itemChange(GraphicsItemChange change, + const QVariant &value) +{ + if (change == ItemPositionHasChanged) + { + m_itemZone->updateZone(); + } + return QGraphicsItem::itemChange(change, value); +} + +void GraphicsItemNode::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + if ((m_type == MiddleType) && (event->button() == Qt::LeftButton)) + { + m_itemZone->updateMiddleNode(this); + setNodeType(EdgeType); + } + else if ((m_type == EdgeType) && (event->button() == Qt::RightButton)) + { + if (m_itemZone->deleteEdgePoint(this)) + setNodeType(MiddleType); + } +} + +GraphicsItemZone::GraphicsItemZone(QGraphicsScene *scene, QGraphicsItem *parent) + : QGraphicsPolygonItem(parent) +{ + m_scene = scene; + + m_color = QColor(12, 150, 215); + + setBrush(QBrush(QColor(100, 100, 255, 128))); + updateZone(); + setZValue(100); + //setFlag(ItemClipsToShape); + //setFlag(ItemIsSelectable, true); + //setFlag(ItemIsMovable, true); + //setFlag(ItemHasNoContents, true); +} + +GraphicsItemZone::~GraphicsItemZone() +{ +} + +void GraphicsItemZone::updateMiddleNode(GraphicsItemNode *node) +{ + for (int i = 0; i < m_listLines.size(); ++i) + { + if (node == m_listLines.at(i).itemPoint) + { + LineItem oldLineItem = m_listLines[i]; + + GraphicsItemNode *newNode1 = new GraphicsItemNode(this); + newNode1->setPos((oldLineItem.lineNode.first->pos() + node->pos()) / 2); + newNode1->setNodeType(GraphicsItemNode::MiddleType); + m_scene->addItem(newNode1); + + GraphicsItemNode *newNode2 = new GraphicsItemNode(this); + newNode2->setPos((oldLineItem.lineNode.second->pos() + node->pos()) / 2); + newNode2->setNodeType(GraphicsItemNode::MiddleType); + m_scene->addItem(newNode2); + + LineItem newLineItem1; + newLineItem1.itemPoint = newNode1; + newLineItem1.lineNode = LineNode(oldLineItem.lineNode.first, node); + m_listLines.push_back(newLineItem1); + + LineItem newLineItem2; + newLineItem2.itemPoint = newNode2; + newLineItem2.lineNode = LineNode(node, oldLineItem.lineNode.second); + m_listLines.push_back(newLineItem2); + + m_listLines.removeAt(i); + + int pos = m_listItems.indexOf(oldLineItem.lineNode.second); + m_listItems.insert(pos, node); + + break; + } + } +} + +bool GraphicsItemZone::deleteEdgePoint(GraphicsItemNode *node) +{ + if (m_listItems.size() < 4) + return false; + + int pos = m_listItems.indexOf(node); + m_listItems.takeAt(pos); + + LineItem newLineItem; + + newLineItem.itemPoint = node; + + for (int i = 0; i < m_listLines.size(); ++i) + { + if (node == m_listLines.at(i).lineNode.first) + { + // Saving second point for new line + newLineItem.lineNode.second = m_listLines.at(i).lineNode.second; + delete m_listLines.at(i).itemPoint; + m_listLines.removeAt(i); + break; + } + } + + for (int i = 0; i < m_listLines.size(); ++i) + { + if (node == m_listLines.at(i).lineNode.second) + { + newLineItem.lineNode.first = m_listLines.at(i).lineNode.first; + delete m_listLines.at(i).itemPoint; + m_listLines.removeAt(i); + break; + } + } + node->setPos((newLineItem.lineNode.first->pos() + newLineItem.lineNode.second->pos()) / 2); + m_listLines.push_back(newLineItem); + + return true; +} + +void GraphicsItemZone::scanPolygon(const QPolygonF &polygon) +{ + GraphicsItemNode *node1; + node1 = new GraphicsItemNode(this); + node1->setPos(*polygon.begin()); + m_listItems.push_back(node1); + m_scene->addItem(node1); + for (int i = 1; i < polygon.count(); ++i) + { + GraphicsItemNode *node2 = new GraphicsItemNode(this); + node2->setPos(polygon.at(i)); + m_listItems.push_back(node2); + + GraphicsItemNode *node3 = new GraphicsItemNode(this); + node3->setPos((node1->pos() + node2->pos()) / 2); + node3->setNodeType(GraphicsItemNode::MiddleType); + m_scene->addItem(node3); + + LineItem newLineItem; + newLineItem.itemPoint = node3; + newLineItem.lineNode = LineNode(node1, node2); + m_listLines.push_back(newLineItem); + + node1 = node2; + m_scene->addItem(node1); + } + setPolygon(polygon); +} + +void GraphicsItemZone::updateZone() +{ + QPolygonF polygon; + Q_FOREACH(GraphicsItemNode *node, m_listItems) + { + polygon << node->pos(); + } + + for (int i = 0; i < m_listLines.size(); ++i) + { + m_listLines.at(i).itemPoint->setPos((m_listLines.at(i).lineNode.first->pos() + m_listLines.at(i).lineNode.second->pos()) / 2); + } + + setPolygon(polygon); +} +*/ + +AbstractWorldItem::AbstractWorldItem(QGraphicsItem *parent) + : QGraphicsItem(parent) +{ +} + +AbstractWorldItem::~AbstractWorldItem() +{ +} + +int AbstractWorldItem::type() const +{ + return Type; +} + +WorldItemPoint::WorldItemPoint(const QPointF &point, const float angle, QGraphicsItem *parent) + : AbstractWorldItem(parent), + m_angle(angle) +{ + setZValue(WORLD_POINT_LAYER); + + setPos(point); + + m_rect.setCoords(-SIZE_POINT, -SIZE_POINT, SIZE_POINT, SIZE_POINT); + + m_pen.setColor(QColor(255, 100, 10)); + m_pen.setWidth(5); + + m_selectedPen.setColor(QColor(0, 255, 0)); + m_selectedPen.setWidth(5); + + m_brush.setColor(QColor(255, 100, 10)); + m_brush.setStyle(Qt::SolidPattern); + + m_selectedBrush.setColor(QColor(0, 255, 0)); + m_selectedBrush.setStyle(Qt::SolidPattern); + + //setFlag(ItemIsSelectable); +} + +WorldItemPoint::~WorldItemPoint() +{ +} + +void WorldItemPoint::moveOn(const QPointF &offset) +{ + prepareGeometryChange(); + + setPos(pos() + offset); +} + +void WorldItemPoint::rotateOn(const QPointF &pivot, const qreal deltaAngle) +{ + prepareGeometryChange(); + + QPolygonF rotatedPolygon(m_rect); + + // TODO + rotatedPolygon.translate(pos()); + rotatedPolygon.translate(-pivot); + + QTransform trans; + trans = trans.rotate(deltaAngle); + rotatedPolygon = trans.map(rotatedPolygon); + rotatedPolygon.translate(pivot); + + setPos(rotatedPolygon.boundingRect().center()); +} + +void WorldItemPoint::scaleOn(const QPointF &pivot, const QPointF &offset) +{ + prepareGeometryChange(); + + QPolygonF scaledPolygon(m_rect); + + // TODO + scaledPolygon.translate(pos()); + scaledPolygon.translate(-pivot); + + QTransform trans; + trans = trans.scale(1.0 + (offset.x() / 5000), 1.0 + (-offset.y() / 5000)); + scaledPolygon = trans.map(scaledPolygon); + scaledPolygon.translate(pivot); + + setPos(scaledPolygon.boundingRect().center()); +} + +void WorldItemPoint::turnOn(const QPointF &offset) +{ +} + +void WorldItemPoint::radiusOn(const qreal radius) +{ +} + +QPainterPath WorldItemPoint::shape() const +{ + QPainterPath path; + + path.addRect(m_rect); + + return qt_graphicsItem_shapeFromPath(path, m_pen); +} + +QRectF WorldItemPoint::boundingRect() const +{ + return m_rect; +} + +void WorldItemPoint::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *) +{ + // Here comes the magic: + //painter->setClipRect(option->exposedRect); + + painter->setPen(Qt::NoPen); + + if (option->state & QStyle::State_Selected) + { + painter->setBrush(m_selectedBrush); + } + else + { + painter->setBrush(m_brush); + } + + painter->drawRect(m_rect); +} + +QVariant WorldItemPoint::itemChange(GraphicsItemChange change, const QVariant &value) +{ + if (change == ItemPositionHasChanged) + { + } + return QGraphicsItem::itemChange(change, value); +} + +WorldItemPath::WorldItemPath(const QPolygonF &polygon, QGraphicsItem *parent) + : AbstractWorldItem(parent), + m_polygon(polygon) +{ + //setFlag(ItemIsSelectable); + + setZValue(WORLD_PATH_LAYER); + + m_pen.setColor(QColor(0, 0, 0)); + m_pen.setWidth(5); + + m_selectedPen.setColor(QColor(255, 0, 0)); + m_selectedPen.setWidth(5); +} + +WorldItemPath::~WorldItemPath() +{ +} + +void WorldItemPath::moveOn(const QPointF &offset) +{ + prepareGeometryChange(); + + m_polygon.translate(offset); +} + +void WorldItemPath::rotateOn(const QPointF &pivot, const qreal deltaAngle) +{ + prepareGeometryChange(); + + QPolygonF rotatedPolygon(m_polygon); + rotatedPolygon.translate(-pivot); + + QTransform trans; + trans = trans.rotate(deltaAngle); + m_polygon = trans.map(rotatedPolygon); + + m_polygon.translate(pivot); +} + +void WorldItemPath::scaleOn(const QPointF &pivot, const QPointF &offset) +{ + prepareGeometryChange(); + + QPolygonF scaledPolygon(m_polygon); + scaledPolygon.translate(-pivot); + + QTransform trans; + trans = trans.scale(1.0 + (offset.x() / 5000), 1.0 + (-offset.y() / 5000)); + m_polygon = trans.map(scaledPolygon); + + m_polygon.translate(pivot); +} + +void WorldItemPath::turnOn(const QPointF &offset) +{ +} + +void WorldItemPath::radiusOn(const qreal radius) +{ +} + +QPainterPath WorldItemPath::shape() const +{ + QPainterPath path; + + path.moveTo(m_polygon.first()); + for (int i = 1; i < m_polygon.count(); ++i) + path.lineTo(m_polygon.at(i)); + + return qt_graphicsItem_shapeFromPath(path, m_pen); +} + +QRectF WorldItemPath::boundingRect() const +{ + return m_polygon.boundingRect(); +} + +void WorldItemPath::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *) +{ + // Here comes the magic: + //painter->setClipRect(option->exposedRect); + + if (option->state & QStyle::State_Selected) + painter->setPen(m_selectedPen); + else + painter->setPen(m_pen); + + painter->drawPolyline(m_polygon); +} + +QVariant WorldItemPath::itemChange(GraphicsItemChange change, const QVariant &value) +{ + if (change == ItemPositionHasChanged) + { + } + return QGraphicsItem::itemChange(change, value); +} + +WorldItemZone::WorldItemZone(const QPolygonF &polygon, QGraphicsItem *parent) + : AbstractWorldItem(parent), + m_polygon(polygon) +{ + //setFlag(ItemIsSelectable); + + setZValue(WORLD_ZONE_LAYER); + + m_pen.setColor(QColor(20, 100, 255)); + m_pen.setWidth(0); + + m_selectedPen.setColor(QColor(255, 0, 0)); + m_selectedPen.setWidth(0); + + m_brush.setColor(QColor(20, 100, 255, 28)); + m_brush.setStyle(Qt::SolidPattern); + + m_selectedBrush.setColor(QColor(255, 0, 0, 128)); + m_selectedBrush.setStyle(Qt::SolidPattern); +} + +WorldItemZone::~WorldItemZone() +{ +} + +void WorldItemZone::moveOn(const QPointF &offset) +{ + prepareGeometryChange(); + + m_polygon.translate(offset); +} + +void WorldItemZone::rotateOn(const QPointF &pivot, const qreal deltaAngle) +{ + prepareGeometryChange(); + + QPolygonF rotatedPolygon(m_polygon); + rotatedPolygon.translate(-pivot); + + QTransform trans; + trans = trans.rotate(deltaAngle); + m_polygon = trans.map(rotatedPolygon); + + m_polygon.translate(pivot); +} + +void WorldItemZone::scaleOn(const QPointF &pivot, const QPointF &offset) +{ + prepareGeometryChange(); + + QPolygonF scaledPolygon(m_polygon); + scaledPolygon.translate(-pivot); + + QTransform trans; + trans = trans.scale(1.0 + (offset.x() / 5000), 1.0 + (-offset.y() / 5000)); + m_polygon = trans.map(scaledPolygon); + + m_polygon.translate(pivot); +} + +void WorldItemZone::turnOn(const QPointF &offset) +{ +} + +void WorldItemZone::radiusOn(const qreal radius) +{ +} + +QRectF WorldItemZone::boundingRect() const +{ + return m_polygon.boundingRect(); +} + +QPainterPath WorldItemZone::shape() const +{ + QPainterPath path; + path.addPolygon(m_polygon); + return qt_graphicsItem_shapeFromPath(path, m_pen); +} + +void WorldItemZone::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *) +{ + if (option->state & QStyle::State_Selected) + { + painter->setPen(m_selectedPen); + painter->setBrush(m_selectedBrush); + } + else + { + painter->setPen(m_pen); + painter->setBrush(m_brush); + } + + painter->drawPolygon(m_polygon); +} + +QVariant WorldItemZone::itemChange(GraphicsItemChange change, const QVariant &value) +{ + if (change == ItemPositionHasChanged) + { + } + return QGraphicsItem::itemChange(change, value); +} + +} /* namespace WorldEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h new file mode 100644 index 000000000..6c144518c --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h @@ -0,0 +1,237 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +#ifndef WORLD_EDITOR_SCENE_ITEM_H +#define WORLD_EDITOR_SCENE_ITEM_H + +// Project includes +#include "world_editor_global.h" + +// NeL includes + +// Qt includes +#include +#include +#include +#include +#include +#include + +namespace WorldEditor +{ +class GraphicsItemZone; +class GraphicsItemNode; + +typedef QPair LineNode; + +const int SELECTED_LAYER = 200; +const int UNSELECTED_LAYER = 100; +const int WORLD_ZONE_LAYER = 100; +const int WORLD_POINT_LAYER = 200; +const int WORLD_PATH_LAYER = 200; +const int MIDDLE_POINT_LAYER = 201; +const int EDGE_POINT_LAYER = 201; + +/* +// Deprecated +class GraphicsItemNode: public QGraphicsObject +{ + Q_OBJECT + Q_PROPERTY(QColor colorNode READ colorNode WRITE setColorNode) +public: + enum NodeType + { + EdgeType = 0, + MiddleType + }; + + GraphicsItemNode(GraphicsItemZone *itemZone, QGraphicsItem *parent = 0); + virtual ~GraphicsItemNode(); + + void setColorNode(const QColor &color); + QColor colorNode() const + { + return m_color; + } + + void setNodeType(NodeType nodeType); + + virtual QRectF boundingRect() const; + //QPainterPath shape() const; + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + +protected: + virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value); + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + +private: + + NodeType m_type; + GraphicsItemZone *m_itemZone; + QColor m_color; +}; + +// Deprecated +class GraphicsItemZone: public QGraphicsPolygonItem +{ +public: + GraphicsItemZone(QGraphicsScene *scene, QGraphicsItem *parent = 0); + virtual ~GraphicsItemZone(); + + void scanPolygon(const QPolygonF &polygon); + void updateMiddleNode(GraphicsItemNode *node); + bool deleteEdgePoint(GraphicsItemNode *node); + //void addNode(GraphicsItemNode *node); + void updateZone(); + //QRectF boundingRect() const; + //void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + +protected: + // QVariant itemChange(GraphicsItemChange change, const QVariant &value); + +private: + struct LineItem + { + GraphicsItemNode *itemPoint; + LineNode lineNode; + }; + QGraphicsScene *m_scene; + QColor m_color; + QList m_listItems; + QList m_listLines; +}; +*/ + +/* +@class WorldItemPoint +@brief +@details +*/ +class AbstractWorldItem: public QGraphicsItem +{ +public: + AbstractWorldItem(QGraphicsItem *parent = 0); + virtual ~AbstractWorldItem(); + + enum { Type = QGraphicsItem::UserType + 1 }; + + virtual void moveOn(const QPointF &offset) = 0; + virtual void rotateOn(const QPointF &pivot, const qreal deltaAngle) = 0; + // TODO: add modes: IgnoreAspectRatio, KeepAspectRatio + virtual void scaleOn(const QPointF &pivot, const QPointF &offset) = 0; + virtual void turnOn(const QPointF &offset) = 0; + virtual void radiusOn(const qreal radius) = 0; + + // Enable the use of qgraphicsitem_cast with this item. + int type() const; +}; + +/* +@class WorldItemPoint +@brief +@details +*/ +class WorldItemPoint: public AbstractWorldItem +{ +public: + WorldItemPoint(const QPointF &point, const float angle, QGraphicsItem *parent = 0); + virtual ~WorldItemPoint(); + + virtual void moveOn(const QPointF &offset); + virtual void rotateOn(const QPointF &pivot, const qreal deltaAngle); + virtual void scaleOn(const QPointF &pivot, const QPointF &offset); + virtual void turnOn(const QPointF &offset); + virtual void radiusOn(const qreal radius); + + virtual QRectF boundingRect() const; + virtual QPainterPath shape() const; + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + +protected: + virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value); + +private: + + // TODO + static const int SIZE_POINT = 7; + + QPen m_pen, m_selectedPen; + QBrush m_brush, m_selectedBrush; + + QRectF m_rect; + float m_angle; +}; + +/* +@class WorldItemPath +@brief +@details +*/ +class WorldItemPath: public AbstractWorldItem +{ +public: + WorldItemPath(const QPolygonF &polygon, QGraphicsItem *parent = 0); + virtual ~WorldItemPath(); + + virtual void moveOn(const QPointF &offset); + virtual void rotateOn(const QPointF &pivot, const qreal deltaAngle); + virtual void scaleOn(const QPointF &pivot, const QPointF &offset); + virtual void turnOn(const QPointF &offset); + virtual void radiusOn(const qreal radius); + + virtual QRectF boundingRect() const; + virtual QPainterPath shape() const; + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + +protected: + virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value); + + QPen m_pen, m_selectedPen; + QPolygonF m_polygon; +}; + +/* +@class WorldItemZone +@brief +@details +*/ +class WorldItemZone: public AbstractWorldItem +{ +public: + WorldItemZone(const QPolygonF &polygon, QGraphicsItem *parent = 0); + virtual ~WorldItemZone(); + + virtual void moveOn(const QPointF &offset); + virtual void rotateOn(const QPointF &pivot, const qreal deltaAngle); + virtual void scaleOn(const QPointF &pivot, const QPointF &offset); + virtual void turnOn(const QPointF &offset); + virtual void radiusOn(const qreal radius); + + virtual QRectF boundingRect() const; + virtual QPainterPath shape() const; + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + +protected: + virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value); + + QPen m_pen, m_selectedPen; + QBrush m_brush, m_selectedBrush; + QPolygonF m_polygon; +}; + +} /* namespace WorldEditor */ + +#endif // WORLD_EDITOR_SCENE_ITEM_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp index 132b52b70..ac46491f3 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp @@ -21,6 +21,8 @@ #include "world_editor_scene.h" #include "world_editor_misc.h" #include "world_editor_actions.h" +#include "world_editor_scene_item.h" +#include "project_settings_dialog.h" // Core #include "../core/icore.h" @@ -31,14 +33,9 @@ #include "../landscape_editor/builder_zone_base.h" // NeL includes -#include -#include -#include -#include // Qt includes #include -#include #include namespace WorldEditor @@ -57,6 +54,7 @@ WorldEditorWindow::WorldEditorWindow(QWidget *parent) m_worldEditorScene->setZoneBuilder(m_zoneBuilderBase); m_ui.graphicsView->setScene(m_worldEditorScene); + m_ui.graphicsView->setVisibleText(false); QActionGroup *sceneModeGroup = new QActionGroup(this); sceneModeGroup->addAction(m_ui.selectAction); @@ -70,20 +68,38 @@ WorldEditorWindow::WorldEditorWindow(QWidget *parent) m_ui.newWorldEditAction->setIcon(QIcon(Core::Constants::ICON_NEW)); m_ui.saveWorldEditAction->setIcon(QIcon(Core::Constants::ICON_SAVE)); - m_primitivesModel = new PrimitivesTreeModel(); + m_primitivesModel = new PrimitivesTreeModel(this); m_ui.treePrimitivesView->setModel(m_primitivesModel); // TODO: ? m_ui.treePrimitivesView->setUndoStack(m_undoStack); m_ui.treePrimitivesView->setZoneBuilder(m_zoneBuilderBase); + m_ui.treePrimitivesView->setWorldScene(m_worldEditorScene); createMenus(); createToolBars(); readSettings(); + QSignalMapper *m_modeMapper = new QSignalMapper(this); + connect(m_ui.selectAction, SIGNAL(triggered()), m_modeMapper, SLOT(map())); + m_modeMapper->setMapping(m_ui.selectAction, 0); + connect(m_ui.moveAction, SIGNAL(triggered()), m_modeMapper, SLOT(map())); + m_modeMapper->setMapping(m_ui.moveAction, 1); + connect(m_ui.rotateAction, SIGNAL(triggered()), m_modeMapper, SLOT(map())); + m_modeMapper->setMapping(m_ui.rotateAction, 2); + connect(m_ui.scaleAction, SIGNAL(triggered()), m_modeMapper, SLOT(map())); + m_modeMapper->setMapping(m_ui.scaleAction, 3); + connect(m_ui.turnAction, SIGNAL(triggered()), m_modeMapper, SLOT(map())); + m_modeMapper->setMapping(m_ui.turnAction, 4); + connect(m_ui.radiusAction, SIGNAL(triggered()), m_modeMapper, SLOT(map())); + m_modeMapper->setMapping(m_ui.radiusAction, 5); + + connect(m_modeMapper, SIGNAL(mapped(int)), this, SLOT(setMode(int))); + connect(m_ui.pointsAction, SIGNAL(triggered(bool)), m_worldEditorScene, SLOT(setEnabledEditPoint(bool))); + + connect(m_ui.settingsAction, SIGNAL(triggered()), this, SLOT(openProjectSettings())); connect(m_ui.newWorldEditAction, SIGNAL(triggered()), this, SLOT(newWorldEditFile())); connect(m_ui.saveWorldEditAction, SIGNAL(triggered()), this, SLOT(saveWorldEditFile())); - } WorldEditorWindow::~WorldEditorWindow() @@ -118,6 +134,7 @@ void WorldEditorWindow::loadWorldEditFile(const QString &fileName) Utils::WorldEditList worldEditList; if (!Utils::loadWorldEditFile(fileName.toStdString(), worldEditList)) { + // TODO: add the message box return; } @@ -139,7 +156,7 @@ void WorldEditorWindow::loadWorldEditFile(const QString &fileName) 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)); + m_undoStack->push(new LoadRootPrimitiveCommand(QString(worldEditList[i].second.c_str()), m_worldEditorScene, m_primitivesModel)); break; }; } @@ -163,15 +180,55 @@ 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; - */ + ProjectSettingsDialog *dialog = new ProjectSettingsDialog(m_zoneBuilderBase->dataPath(), this); + dialog->show(); + int ok = dialog->exec(); + if (ok == QDialog::Accepted) + { + m_zoneBuilderBase->init(dialog->dataPath(), true); + } + delete dialog; +} + +void WorldEditorWindow::setMode(int value) +{ + switch (value) + { + case 0: + m_worldEditorScene->setModeEdit(WorldEditorScene::SelectMode); + break; + case 1: + m_worldEditorScene->setModeEdit(WorldEditorScene::MoveMode); + break; + case 2: + m_worldEditorScene->setModeEdit(WorldEditorScene::RotateMode); + break; + case 3: + m_worldEditorScene->setModeEdit(WorldEditorScene::ScaleMode); + break; + case 4: + m_worldEditorScene->setModeEdit(WorldEditorScene::TurnMode); + break; + case 5: + m_worldEditorScene->setModeEdit(WorldEditorScene::RadiusMode); + break; + } +} + +void WorldEditorWindow::showEvent(QShowEvent *showEvent) +{ + QMainWindow::showEvent(showEvent); + if (m_oglWidget != 0) + m_oglWidget->makeCurrent(); + //m_statusInfo->show(); + //m_statusBarTimer->start(100); +} + +void WorldEditorWindow::hideEvent(QHideEvent *hideEvent) +{ + QMainWindow::hideEvent(hideEvent); + //m_statusInfo->hide(); + //m_statusBarTimer->stop(); } void WorldEditorWindow::createMenus() @@ -211,6 +268,14 @@ void WorldEditorWindow::readSettings() settings->beginGroup(Constants::WORLD_EDITOR_SECTION); restoreState(settings->value(Constants::WORLD_WINDOW_STATE).toByteArray()); restoreGeometry(settings->value(Constants::WORLD_WINDOW_GEOMETRY).toByteArray()); + + // Use OpenGL graphics system instead raster graphics system + if (settings->value(Constants::WORLD_EDITOR_USE_OPENGL, true).toBool()) + { + m_oglWidget = new QGLWidget(QGLFormat(QGL::DoubleBuffer)); + m_ui.graphicsView->setViewport(m_oglWidget); + } + settings->endGroup(); } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h index 2536bcc1c..321c46c3e 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h @@ -22,6 +22,8 @@ // Qt includes #include +#include +#include namespace LandscapeEditor { @@ -52,6 +54,12 @@ private Q_SLOTS: void saveWorldEditFile(); void openProjectSettings(); + void setMode(int value); + +protected: + virtual void showEvent(QShowEvent *showEvent); + virtual void hideEvent(QHideEvent *hideEvent); + private: void createMenus(); void createToolBars(); @@ -67,6 +75,8 @@ private: QUndoStack *m_undoStack; WorldEditorScene *m_worldEditorScene; LandscapeEditor::ZoneBuilderBase *m_zoneBuilderBase; + QSignalMapper m_modeMapper; + QGLWidget *m_oglWidget; Ui::WorldEditorWindow m_ui; }; /* class WorldEditorWindow */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui index 80e4e5ace..37f56ca11 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui @@ -21,8 +21,14 @@ + + true + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + - QGraphicsView::RubberBandDrag + QGraphicsView::NoDrag QGraphicsView::AnchorUnderMouse @@ -30,6 +36,12 @@ QGraphicsView::AnchorUnderMouse + + QGraphicsView::BoundingRectViewportUpdate + + + QGraphicsView::DontAdjustForAntialiasing|QGraphicsView::DontClipPainter + @@ -87,9 +99,6 @@ QAbstractItemView::ExtendedSelection - - true - true @@ -117,6 +126,8 @@ + + @@ -137,19 +148,22 @@ loadLand - + :/icons/ic_nel_landscape_settings.png:/icons/ic_nel_landscape_settings.png - LandSettings + Settings true + + false + S/H Land @@ -158,6 +172,9 @@ true + + false + S/H Primitives @@ -166,6 +183,9 @@ true + + false + S/H Layers @@ -174,6 +194,9 @@ true + + false + S/H Details @@ -182,6 +205,9 @@ true + + false + :/icons/ic_grid.png:/icons/ic_grid.png @@ -194,6 +220,9 @@ true + + false + S/H Grid points @@ -260,6 +289,9 @@ true + + false + :/icons/ic_nel_turn.png:/icons/ic_nel_turn.png @@ -272,6 +304,9 @@ true + + false + Radius @@ -280,10 +315,22 @@ true + + false + Edit points + + + + :/icons/ic_nel_landscape_settings.png:/icons/ic_nel_landscape_settings.png + + + Project settings + + From 3a96a8f8e37b7349b2cf726ef8aa42cc5ce75d8d Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Wed, 10 Aug 2011 03:04:31 +0300 Subject: [PATCH 46/89] Fixed: #1301 Added max and min zooming. --HG-- branch : gsoc2011-worldeditorqt --- .../landscape_editor/landscape_view.cpp | 39 ++++++------------- .../plugins/landscape_editor/landscape_view.h | 2 +- 2 files changed, 13 insertions(+), 28 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp index 6cc6b159e..10e1348df 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp @@ -33,17 +33,15 @@ namespace LandscapeEditor LandscapeView::LandscapeView(QWidget *parent) : QGraphicsView(parent), m_visibleGrid(true), - m_visibleText(false) + m_visibleText(true) { - //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; + m_maxView = 0.06; + m_minView = 32.0; + m_maxViewText = 0.6; //A modified version of centerOn(), handles special cases setCenter(QPointF(500.0, 500.0)); @@ -72,25 +70,7 @@ void LandscapeView::setVisibleText(bool visible) 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);*/ + //nlinfo(QString("%1").arg(transform().m11()).toStdString().c_str()); //Get the position of the mouse before scaling, in scene coords QPointF pointBeforeScale(mapToScene(event->pos())); @@ -102,11 +82,16 @@ void LandscapeView::wheelEvent(QWheelEvent *event) double scaleFactor = 1.15; //How fast we zoom if(event->delta() > 0) { + if (transform().m11() > m_minView ) + return; //Zoom in scale(scaleFactor, scaleFactor); } else { + if (transform().m11() < m_maxView ) + return; + //Zooming out scale(1.0 / scaleFactor, 1.0 / scaleFactor); } @@ -242,7 +227,7 @@ void LandscapeView::drawForeground(QPainter *painter, const QRectF &rect) if (!m_visibleText) return; - if (m_numSteps > -m_maxSteps / 4) + if (transform().m11() > m_maxViewText) { painter->setPen(QPen(Qt::white, 0.5, Qt::SolidLine)); //painter->setFont(QFont("Helvetica [Cronyx]", 12)); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h index 607afe60f..5ce1fb3a7 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h @@ -59,7 +59,7 @@ protected: private: bool m_visibleGrid, m_visibleText; - int m_numSteps, m_maxSteps; + qreal m_maxView, m_minView, m_maxViewText; int m_cellSize; //Holds the current centerpoint for the view, used for panning and zooming From c4c7fe06c035800ea6a2a8b157efff2057b379ab Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Wed, 10 Aug 2011 14:59:23 +0300 Subject: [PATCH 47/89] Changed: #1302 Added status bar and inactive world editor settings page. --HG-- branch : gsoc2011-worldeditorqt --- .../landscape_editor/landscape_scene_base.cpp | 2 +- .../src/plugins/world_editor/CMakeLists.txt | 2 + .../colors_workspace_settings_page.ui | 44 ++++++ .../world_editor/world_editor_plugin.cpp | 5 + .../world_editor_settings_page.cpp | 71 +++++++++ .../world_editor/world_editor_settings_page.h | 59 ++++++++ .../world_editor_settings_page.ui | 137 ++++++++++++++++++ .../world_editor/world_editor_window.cpp | 24 ++- .../world_editor/world_editor_window.h | 6 + .../world_editor/world_editor_window.ui | 5 +- 10 files changed, 348 insertions(+), 7 deletions(-) create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/colors_workspace_settings_page.ui create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_settings_page.cpp create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_settings_page.h create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_settings_page.ui diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene_base.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene_base.cpp index 9ae8d9bbd..2027831ae 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene_base.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene_base.cpp @@ -283,7 +283,7 @@ QString LandscapeSceneBase::zoneNameFromMousePos() const (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))). + return QString("%1_%2%3 %4 %5 ").arg(-m_posY+1).arg(QChar('A' + (m_posX/26))). arg(QChar('A' + (m_posX%26))).arg(m_mouseX, 0,'f',2).arg(-m_mouseY, 0,'f',2); } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/CMakeLists.txt index 07d7fa5d1..7b9387c44 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/CMakeLists.txt +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/CMakeLists.txt @@ -16,10 +16,12 @@ SET(OVQT_PLUGIN_WORLD_EDITOR_HDR world_editor_plugin.h primitives_model.h primitives_view.h project_settings_dialog.h + world_editor_settings_page.h ) SET(OVQT_PLUGIN_WORLD_EDITOR_UIS world_editor_window.ui project_settings_dialog.ui + world_editor_settings_page.ui ) SET(OVQT_PLUGIN_WORLD_EDITOR_RCS world_editor.qrc) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/colors_workspace_settings_page.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/colors_workspace_settings_page.ui new file mode 100644 index 000000000..de6e77901 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/colors_workspace_settings_page.ui @@ -0,0 +1,44 @@ + + + WorldEditorSettingsPage + + + + 0 + 0 + 329 + 239 + + + + Form + + + + + + Colors + + + + + + + + Qt::Vertical + + + + 20 + 0 + + + + + + + + + + + diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_plugin.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_plugin.cpp index 90d2de6d6..051d403ea 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_plugin.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_plugin.cpp @@ -18,6 +18,7 @@ // Project includes #include "world_editor_plugin.h" #include "world_editor_window.h" +#include "world_editor_settings_page.h" #include "../core/icore.h" #include "../core/core_constants.h" @@ -47,6 +48,10 @@ WorldEditorPlugin::~WorldEditorPlugin() bool WorldEditorPlugin::initialize(ExtensionSystem::IPluginManager *pluginManager, QString *errorString) { m_plugMan = pluginManager; + + WorldEditorSettingsPage *weSettings = new WorldEditorSettingsPage(this); + addAutoReleasedObject(weSettings); + QSettings *settings = Core::ICore::instance()->settings(); settings->beginGroup(Constants::WORLD_EDITOR_SECTION); m_ligoConfig.CellSize = settings->value(Constants::WORLD_EDITOR_CELL_SIZE, "160").toFloat(); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_settings_page.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_settings_page.cpp new file mode 100644 index 000000000..f3b3e6551 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_settings_page.cpp @@ -0,0 +1,71 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +// Project includes +#include "world_editor_settings_page.h" +#include "world_editor_constants.h" + +// Qt includes +#include + +// NeL includes + +namespace WorldEditor +{ + +WorldEditorSettingsPage::WorldEditorSettingsPage(QObject *parent) + : IOptionsPage(parent), + m_currentPage(NULL) +{ +} + +QString WorldEditorSettingsPage::id() const +{ + return QLatin1String(Constants::WORLD_EDITOR_PLUGIN); +} + +QString WorldEditorSettingsPage::trName() const +{ + return tr("General"); +} + +QString WorldEditorSettingsPage::category() const +{ + return QLatin1String(Constants::WORLD_EDITOR_PLUGIN); +} + +QString WorldEditorSettingsPage::trCategory() const +{ + return tr("World Editor"); +} + +QIcon WorldEditorSettingsPage::categoryIcon() const +{ + return QIcon(); +} + +QWidget *WorldEditorSettingsPage::createPage(QWidget *parent) +{ + m_currentPage = new QWidget(parent); + m_ui.setupUi(m_currentPage); + return m_currentPage; +} + +void WorldEditorSettingsPage::apply() +{ +} + +} /* namespace WorldEditor */ \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_settings_page.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_settings_page.h new file mode 100644 index 000000000..27cda963e --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_settings_page.h @@ -0,0 +1,59 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + + +#ifndef WORLD_EDITOR_SETTINGS_PAGE_H +#define WORLD_EDITOR_SETTINGS_PAGE_H + +#include + +#include "../core/ioptions_page.h" + +#include "ui_world_editor_settings_page.h" + +class QWidget; + +namespace WorldEditor +{ + +/** +@class WorldEditorSettingsPage +*/ +class WorldEditorSettingsPage : public Core::IOptionsPage +{ + Q_OBJECT +public: + WorldEditorSettingsPage(QObject *parent = 0); + virtual ~WorldEditorSettingsPage() {} + + virtual QString id() const; + virtual QString trName() const; + virtual QString category() const; + virtual QString trCategory() const; + QIcon categoryIcon() const; + virtual QWidget *createPage(QWidget *parent); + + virtual void apply(); + virtual void finish() {} + +private: + QWidget *m_currentPage; + Ui::WorldEditorSettingsPage m_ui; +}; + +} // namespace WorldEditor + +#endif // WORLD_EDITOR_SETTINGS_PAGE_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_settings_page.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_settings_page.ui new file mode 100644 index 000000000..9219da6c4 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_settings_page.ui @@ -0,0 +1,137 @@ + + + WorldEditorSettingsPage + + + false + + + + 0 + 0 + 329 + 239 + + + + Form + + + + 6 + + + 3 + + + + + Workspace + + + + + + Top Left + + + + + + + + + + + + + Bottom Right + + + + + + + + + + + + + Use OpenGL + + + + + + + + + + Ligoscape + + + + + + Cell size + + + + + + + + + + Snap + + + + + + + + + + Ligo class + + + + + + + + + + + + ... + + + + + + + + + + + + Qt::Vertical + + + + 20 + 0 + + + + + + + + + + + diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp index ac46491f3..52c4cd460 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp @@ -37,6 +37,7 @@ // Qt includes #include #include +#include namespace WorldEditor { @@ -54,7 +55,7 @@ WorldEditorWindow::WorldEditorWindow(QWidget *parent) m_worldEditorScene->setZoneBuilder(m_zoneBuilderBase); m_ui.graphicsView->setScene(m_worldEditorScene); - m_ui.graphicsView->setVisibleText(false); + //m_ui.graphicsView->setVisibleText(false); QActionGroup *sceneModeGroup = new QActionGroup(this); sceneModeGroup->addAction(m_ui.selectAction); @@ -100,6 +101,14 @@ WorldEditorWindow::WorldEditorWindow(QWidget *parent) connect(m_ui.settingsAction, SIGNAL(triggered()), this, SLOT(openProjectSettings())); connect(m_ui.newWorldEditAction, SIGNAL(triggered()), this, SLOT(newWorldEditFile())); connect(m_ui.saveWorldEditAction, SIGNAL(triggered()), this, SLOT(saveWorldEditFile())); + connect(m_ui.visibleGridAction, SIGNAL(toggled(bool)), m_ui.graphicsView, SLOT(setVisibleGrid(bool))); + + 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); } WorldEditorWindow::~WorldEditorWindow() @@ -215,20 +224,25 @@ void WorldEditorWindow::setMode(int value) } } +void WorldEditorWindow::updateStatusBar() +{ + m_statusInfo->setText(m_worldEditorScene->zoneNameFromMousePos()); +} + void WorldEditorWindow::showEvent(QShowEvent *showEvent) { QMainWindow::showEvent(showEvent); if (m_oglWidget != 0) m_oglWidget->makeCurrent(); - //m_statusInfo->show(); - //m_statusBarTimer->start(100); + m_statusInfo->show(); + m_statusBarTimer->start(100); } void WorldEditorWindow::hideEvent(QHideEvent *hideEvent) { QMainWindow::hideEvent(hideEvent); - //m_statusInfo->hide(); - //m_statusBarTimer->stop(); + m_statusInfo->hide(); + m_statusBarTimer->stop(); } void WorldEditorWindow::createMenus() diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h index 321c46c3e..65d39ac58 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h @@ -22,6 +22,8 @@ // Qt includes #include +#include +#include #include #include @@ -55,6 +57,7 @@ private Q_SLOTS: void openProjectSettings(); void setMode(int value); + void updateStatusBar(); protected: virtual void showEvent(QShowEvent *showEvent); @@ -71,6 +74,9 @@ private: QString m_lastDir; + QLabel *m_statusInfo; + QTimer *m_statusBarTimer; + PrimitivesTreeModel *m_primitivesModel; QUndoStack *m_undoStack; WorldEditorScene *m_worldEditorScene; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui index 37f56ca11..f5dc5f408 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui @@ -205,8 +205,11 @@ true + + true + - false + true From 1b1bab4cd8b8409bc0c1c356d0b498f7e24c425e Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Wed, 10 Aug 2011 15:00:47 +0300 Subject: [PATCH 48/89] Changed: #1302 Improved selection model. --HG-- branch : gsoc2011-worldeditorqt --- .../world_editor/world_editor_scene.cpp | 58 +++++++++++++------ .../plugins/world_editor/world_editor_scene.h | 5 +- .../world_editor/world_editor_scene_item.cpp | 2 + 3 files changed, 45 insertions(+), 20 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp index fd2d85a24..1e21ee0ec 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp @@ -38,11 +38,17 @@ WorldEditorScene::WorldEditorScene(int sizeCell, QObject *parent) { setItemIndexMethod(NoIndex); - m_pen.setColor(QColor(50, 255, 155)); - m_pen.setWidth(0); + m_pen1.setColor(QColor(50, 255, 155)); + m_pen1.setWidth(0); - m_brush.setColor(QColor(50, 255, 155, 80)); - m_brush.setStyle(Qt::SolidPattern); + m_brush1.setColor(QColor(50, 255, 155, 80)); + m_brush1.setStyle(Qt::SolidPattern); + + m_pen2.setColor(QColor(100, 0, 255)); + m_pen2.setWidth(0); + + m_brush2.setColor(QColor(100, 0, 255, 80)); + m_brush2.setStyle(Qt::SolidPattern); } WorldEditorScene::~WorldEditorScene() @@ -75,8 +81,6 @@ void WorldEditorScene::setModeEdit(WorldEditorScene::ModeEdit mode) if (mode == WorldEditorScene::SelectMode) m_editedSelectedItems = false; - m_selectionArea = QRectF(); - m_mode = mode; } @@ -101,9 +105,18 @@ void WorldEditorScene::drawForeground(QPainter *painter, const QRectF &rect) if ((m_selectionArea.left() != 0) && (m_selectionArea.right() != 0)) { - painter->setPen(m_pen); - painter->setBrush(m_brush); + if (m_selectionArea.left() < m_selectionArea.right()) + { + painter->setPen(m_pen1); + painter->setBrush(m_brush1); + } + else + { + painter->setPen(m_pen2); + painter->setBrush(m_brush2); + } painter->drawRect(m_selectionArea); + } } @@ -117,6 +130,8 @@ void WorldEditorScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) if (mouseEvent->button() != Qt::LeftButton) return; + m_firstPick = mouseEvent->scenePos(); + // if ((!m_editedSelectedItems) && (m_mode != WorldEditorScene::SelectMode)) if ((!m_editedSelectedItems && m_selectedItems.isEmpty()) || (!calcBoundingShape(m_selectedItems).contains(mouseEvent->scenePos()))) @@ -217,7 +232,7 @@ void WorldEditorScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) /*m_mouseX = mouseEvent->scenePos().x(); m_mouseY = mouseEvent->scenePos().y() - m_cellSize; */ - QGraphicsScene::mouseMoveEvent(mouseEvent); + LandscapeEditor::LandscapeSceneBase::mouseMoveEvent(mouseEvent); } void WorldEditorScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent) @@ -261,12 +276,11 @@ void WorldEditorScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent) updatePickSelection(mouseEvent->scenePos()); else m_firstSelection = false; + + m_selectionArea = QRectF(); } -// Huck for standart selection model -// clearSelection(); -// updateSelectedItems(true); - QGraphicsScene::mouseReleaseEvent(mouseEvent); + LandscapeEditor::LandscapeSceneBase::mouseReleaseEvent(mouseEvent); } QRectF WorldEditorScene::calcBoundingRect(const QList &listItems) @@ -317,15 +331,23 @@ void WorldEditorScene::updatePickSelection(const QPointF &point) QList listItems = items(point, Qt::ContainsItemShape, Qt::AscendingOrder); - if (!listItems.isEmpty()) + + QList worldItemsItems; + + Q_FOREACH(QGraphicsItem *item, listItems) + { + AbstractWorldItem *worldItem = qgraphicsitem_cast(item); + if (worldItem != 0) + worldItemsItems.push_back(worldItem); + } + + if (!worldItemsItems.isEmpty()) { // Next primitives m_lastPickedPrimitive++; - m_lastPickedPrimitive %= listItems.size(); - QGraphicsItem *selectedItem = listItems.at(m_lastPickedPrimitive); - if (qgraphicsitem_cast(selectedItem) != 0) - m_selectedItems.push_back(selectedItem); + m_lastPickedPrimitive %= worldItemsItems.size(); + m_selectedItems.push_back(worldItemsItems.at(m_lastPickedPrimitive)); updateSelectedItems(true); } } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h index 36f27b9b4..b97b9672c 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h @@ -80,9 +80,10 @@ private: void updatePickSelection(const QPointF &point); - QPen m_pen; - QBrush m_brush; + QPen m_pen1, m_pen2; + QBrush m_brush1, m_brush2; + QPointF m_firstPick; QRectF m_selectionArea; qreal m_firstPickX, m_firstPickY; QList m_selectedItems; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.cpp index f88c95b9a..d428aed51 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.cpp @@ -328,6 +328,8 @@ WorldItemPoint::WorldItemPoint(const QPointF &point, const float angle, QGraphic { setZValue(WORLD_POINT_LAYER); + //setFlag(ItemIgnoresTransformations); + setPos(point); m_rect.setCoords(-SIZE_POINT, -SIZE_POINT, SIZE_POINT, SIZE_POINT); From a65eb22febc5f8223e5c0463d2001b5d0378c216 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Wed, 10 Aug 2011 17:13:06 +0300 Subject: [PATCH 49/89] Changed: #1302 Used setData(QVariant) instead setGraphicsData(). --HG-- branch : gsoc2011-worldeditorqt --- .../src/plugins/world_editor/primitive_item.cpp | 10 ---------- .../src/plugins/world_editor/primitive_item.h | 10 ++-------- .../src/plugins/world_editor/world_editor_actions.cpp | 11 +++++++++-- .../src/plugins/world_editor/world_editor_constants.h | 7 ++++++- 4 files changed, 17 insertions(+), 21 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.cpp index 672bd2954..e948f8b0f 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.cpp @@ -132,16 +132,6 @@ void Node::setData(int key, const QVariant &data) m_data[key] = data; } -void Node::setGraphicsData(int key, void *pointerToData) -{ - m_graphicsData[key] = pointerToData; -} - -void *Node::graphicsData(int key) const -{ - return m_graphicsData[key]; -} - Node *Node::parent() { return m_parent; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h index 01c96c9d2..4940a622b 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h @@ -35,9 +35,6 @@ class RootPrimitiveNode; class LandscapeNode; class PrimitiveNode; -const int GRAPHICS_DATA_QT2D = 0; -const int GRAPHICS_DATA_NEL3D = 1; - /* @class Node @brief @@ -93,10 +90,6 @@ public: /// Return this node's custom data for the key key as a QVariant. QVariant data(int key) const; - void setGraphicsData(int key, void *pointerToData); - - void *graphicsData(int key) const; - /// Return a type this node. virtual NodeType type() const; @@ -106,7 +99,6 @@ private: Node *m_parent; QList m_children; QHash m_data; - QHash m_graphicsData; }; /* @@ -183,4 +175,6 @@ private: } /* namespace WorldEditor */ +Q_DECLARE_METATYPE(WorldEditor::Node *) + #endif // PRIMITIVE_ITEM_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp index a654e8f31..4f69181c8 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp @@ -16,6 +16,7 @@ // Project includes #include "world_editor_actions.h" +#include "world_editor_constants.h" #include "world_editor_misc.h" #include "primitive_item.h" #include "world_editor_scene.h" @@ -37,6 +38,7 @@ // Qt includes #include +#include namespace WorldEditor { @@ -89,8 +91,13 @@ void addNewGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *mode break; } } + QVariant variantNode; + variantNode.setValue(node); + item->setData(Constants::WORLD_EDITOR_NODE, variantNode); - node->setGraphicsData(GRAPHICS_DATA_QT2D, item); + QVariant graphicsData; + graphicsData.setValue(item); + node->setData(Constants::GRAPHICS_DATA_QT4_2D, graphicsData); } int count = model->rowCount(primIndex); @@ -112,7 +119,7 @@ void removeGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *mode case NLLIGO::CPrimitiveClass::Path: case NLLIGO::CPrimitiveClass::Zone: { - QGraphicsItem *item = static_cast(node->graphicsData(GRAPHICS_DATA_QT2D)); + QGraphicsItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); if (item != 0) delete item; break; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_constants.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_constants.h index 5c1d32908..e0bdc4705 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_constants.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_constants.h @@ -1,5 +1,4 @@ // Object Viewer Qt - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited // Copyright (C) 2011 Dzmitry Kamiahin // // This program is free software: you can redistribute it and/or modify @@ -24,6 +23,12 @@ namespace Constants { const char *const WORLD_EDITOR_PLUGIN = "WorldEditor"; +const int USER_TYPE = 65536; +const int NODE_PERISTENT_INDEX = USER_TYPE + 1; +const int WORLD_EDITOR_NODE = USER_TYPE + 2; +const int GRAPHICS_DATA_QT4_2D = USER_TYPE + 3; +const int GRAPHICS_DATA_NEL3D = USER_TYPE + 4; + //settings const char *const WORLD_EDITOR_SECTION = "WorldEditor"; const char *const WORLD_WINDOW_STATE = "WorldWindowState"; From 89a92f1e4cf2dc594c6b0b96337a02fae0c0c432 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Wed, 10 Aug 2011 23:58:55 +0300 Subject: [PATCH 50/89] Changed: #1302 Added undo command (move, rotate, scale) --HG-- branch : gsoc2011-worldeditorqt --- .../plugins/world_editor/primitives_model.cpp | 22 +++ .../plugins/world_editor/primitives_model.h | 4 +- .../world_editor/world_editor_actions.cpp | 138 ++++++++++++++++++ .../world_editor/world_editor_actions.h | 73 ++++++++- .../world_editor/world_editor_scene.cpp | 82 +++++++++-- .../plugins/world_editor/world_editor_scene.h | 8 +- .../world_editor/world_editor_scene_item.cpp | 12 +- .../world_editor/world_editor_scene_item.h | 10 +- .../world_editor/world_editor_window.cpp | 20 +-- 9 files changed, 333 insertions(+), 36 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.cpp index bc8925175..f59cb8d67 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.cpp @@ -148,6 +148,18 @@ Path PrimitivesTreeModel::pathFromIndex(const QModelIndex &index) return path; } +Path PrimitivesTreeModel::pathFromNode(Node *node) +{ + Node *iter = node; + Path path; + while(iter != 0) + { + path.prepend(PathItem(iter->row(), 1)); + iter = iter->parent(); + } + return path; +} + QModelIndex PrimitivesTreeModel::pathToIndex(const Path &path) { QModelIndex iter; @@ -158,6 +170,16 @@ QModelIndex PrimitivesTreeModel::pathToIndex(const Path &path) return iter; } +Node *PrimitivesTreeModel::pathToNode(const Path &path) +{ + Node *node = m_rootNode; + for(int i = 1; i < path.size(); i++) + { + node = node->child(path[i].first); + } + return node; +} + void PrimitivesTreeModel::createWorldEditNode(const QString &fileName) { beginResetModel(); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.h index 7f9a90aa7..c3c6a3e51 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.h @@ -68,10 +68,12 @@ public: /// @Path is a list of [row,column] pairs showing us the way through the model. Path pathFromIndex(const QModelIndex &index); - //Path pathFromNode(Node *index); + Path pathFromNode(Node *node); QModelIndex pathToIndex(const Path &path); + Node *pathToNode(const Path &path); + void createWorldEditNode(const QString &fileName); void deleteWorldEditNode(); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp index 4f69181c8..c6ed1ee3e 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp @@ -134,6 +134,24 @@ void removeGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *mode } } +QList graphicsItemsToPaths(const QList &items, PrimitivesTreeModel *model) +{ + QList result; + Q_FOREACH(QGraphicsItem *item, items) + { + Node *node = qvariant_cast(item->data(Constants::WORLD_EDITOR_NODE)); + result.push_back(model->pathFromNode(node)); + } + return result; +} + +/* +QList pathsToGraphicsItems(const QList &items, PrimitivesTreeModel *model) +{ + QList result; +} +*/ + CreateWorldCommand::CreateWorldCommand(const QString &fileName, PrimitivesTreeModel *model, QUndoCommand *parent) : QUndoCommand(parent), m_fileName(fileName), @@ -325,4 +343,124 @@ void AddPrimitiveByClassCommand::redo() m_newPrimIndex = m_model->createPrimitiveNode(newPrimitive, m_parentIndex); } +MoveWorldItemsCommand::MoveWorldItemsCommand(const QList &items, const QPointF &offset, + PrimitivesTreeModel *model, QUndoCommand *parent) + : QUndoCommand(parent), + m_listPaths(graphicsItemsToPaths(items, model)), + m_offset(offset), + m_model(model), + m_firstRun(true) +{ + setText("Move item(s)"); +} + +MoveWorldItemsCommand::~MoveWorldItemsCommand() +{ +} + +void MoveWorldItemsCommand::undo() +{ + for (int i = 0; i < m_listPaths.count(); ++i) + { + Node *node = m_model->pathToNode(m_listPaths.at(i)); + QGraphicsItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); + qgraphicsitem_cast(item)->moveOn(-m_offset); + } +} + +void MoveWorldItemsCommand::redo() +{ + if (!m_firstRun) + { + for (int i = 0; i < m_listPaths.count(); ++i) + { + Node *node = m_model->pathToNode(m_listPaths.at(i)); + QGraphicsItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); + qgraphicsitem_cast(item)->moveOn(m_offset); + } + } + m_firstRun = false; +} + +RotateWorldItemsCommand::RotateWorldItemsCommand(const QList &items, const qreal &angle, + const QPointF &pivot, PrimitivesTreeModel *model, QUndoCommand *parent) + : QUndoCommand(parent), + m_listPaths(graphicsItemsToPaths(items, model)), + m_angle(angle), + m_pivot(pivot), + m_model(model), + m_firstRun(true) +{ + setText("Rotate item(s)"); +} + +RotateWorldItemsCommand::~RotateWorldItemsCommand() +{ +} + +void RotateWorldItemsCommand::undo() +{ + for (int i = 0; i < m_listPaths.count(); ++i) + { + Node *node = m_model->pathToNode(m_listPaths.at(i)); + QGraphicsItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); + qgraphicsitem_cast(item)->rotateOn(m_pivot, -m_angle); + } +} + +void RotateWorldItemsCommand::redo() +{ + if (!m_firstRun) + { + for (int i = 0; i < m_listPaths.count(); ++i) + { + Node *node = m_model->pathToNode(m_listPaths.at(i)); + QGraphicsItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); + qgraphicsitem_cast(item)->rotateOn(m_pivot, m_angle); + } + } + m_firstRun = false; +} + +ScaleWorldItemsCommand::ScaleWorldItemsCommand(const QList &items, const QPointF &factor, + const QPointF &pivot, PrimitivesTreeModel *model, QUndoCommand *parent) + : QUndoCommand(parent), + m_listPaths(graphicsItemsToPaths(items, model)), + m_factor(factor), + m_pivot(pivot), + m_model(model), + m_firstRun(true) +{ + setText("Scale item(s)"); +} + +ScaleWorldItemsCommand::~ScaleWorldItemsCommand() +{ +} + +void ScaleWorldItemsCommand::undo() +{ + QPointF m_invertFactor(1 / m_factor.x(), 1 / m_factor.y()); + for (int i = 0; i < m_listPaths.count(); ++i) + { + Node *node = m_model->pathToNode(m_listPaths.at(i)); + QGraphicsItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); + qgraphicsitem_cast(item)->scaleOn(m_pivot, m_invertFactor); + } +} + +void ScaleWorldItemsCommand::redo() +{ + if (!m_firstRun) + { + for (int i = 0; i < m_listPaths.count(); ++i) + { + Node *node = m_model->pathToNode(m_listPaths.at(i)); + QGraphicsItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); + qgraphicsitem_cast(item)->scaleOn(m_pivot, m_factor); + } + } + m_firstRun = false; +} + } /* namespace WorldEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h index 7393861b0..7fd2015e0 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h @@ -38,6 +38,8 @@ class WorldEditorScene; void addNewGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *model, WorldEditorScene *scene); void removeGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *model, WorldEditorScene *scene); +QList graphicsItemsToPaths(const QList &items, PrimitivesTreeModel *model); +//QList pathsToGraphicsItems(const QList &items, PrimitivesTreeModel *model); /** @class CreateWorldCommand @@ -84,7 +86,8 @@ private: class CreateRootPrimitiveCommand: public QUndoCommand { public: - CreateRootPrimitiveCommand(const QString &fileName, PrimitivesTreeModel *model, QUndoCommand *parent = 0); + CreateRootPrimitiveCommand(const QString &fileName, PrimitivesTreeModel *model, + QUndoCommand *parent = 0); virtual ~CreateRootPrimitiveCommand(); virtual void undo(); @@ -139,6 +142,74 @@ private: PrimitivesTreeModel *m_model; }; +/** +@class MoveWorldItemsCommand +@brief +@details +*/ +class MoveWorldItemsCommand: public QUndoCommand +{ +public: + MoveWorldItemsCommand(const QList &items, const QPointF &offset, + PrimitivesTreeModel *model, QUndoCommand *parent = 0); + virtual ~MoveWorldItemsCommand(); + + virtual void undo(); + virtual void redo(); +private: + + const QList m_listPaths; + const QPointF m_offset; + PrimitivesTreeModel *const m_model; + bool m_firstRun; +}; + +/** +@class RotateWorldItemsCommand +@brief +@details +*/ +class RotateWorldItemsCommand: public QUndoCommand +{ +public: + RotateWorldItemsCommand(const QList &items, const qreal &angle, + const QPointF &pivot, PrimitivesTreeModel *model, QUndoCommand *parent = 0); + virtual ~RotateWorldItemsCommand(); + + virtual void undo(); + virtual void redo(); +private: + + const QList m_listPaths; + const qreal m_angle; + const QPointF m_pivot; + PrimitivesTreeModel *const m_model; + bool m_firstRun; +}; + +/** +@class ScaleWorldItemsCommand +@brief +@details +*/ +class ScaleWorldItemsCommand: public QUndoCommand +{ +public: + ScaleWorldItemsCommand(const QList &items, const QPointF &factor, + const QPointF &pivot, PrimitivesTreeModel *model, QUndoCommand *parent = 0); + virtual ~ScaleWorldItemsCommand(); + + virtual void undo(); + virtual void redo(); +private: + + const QList m_listPaths; + const QPointF m_factor; + const QPointF m_pivot; + PrimitivesTreeModel *const m_model; + bool m_firstRun; +}; + } /* namespace WorldEditor */ #endif // WORLD_EDITOR_ACTIONS_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp index 1e21ee0ec..f722bea25 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp @@ -16,6 +16,8 @@ // Project includes #include "world_editor_scene.h" +#include "world_editor_scene_item.h" +#include "world_editor_actions.h" // NeL includes #include @@ -29,12 +31,14 @@ namespace WorldEditor { -WorldEditorScene::WorldEditorScene(int sizeCell, QObject *parent) +WorldEditorScene::WorldEditorScene(int sizeCell, PrimitivesTreeModel *model, QUndoStack *undoStack, QObject *parent) : LandscapeEditor::LandscapeSceneBase(sizeCell, parent), m_editedSelectedItems(false), m_lastPickedPrimitive(0), m_mode(SelectMode), - m_editMode(false) + m_editMode(false), + m_undoStack(undoStack), + m_model(model) { setItemIndexMethod(NoIndex); @@ -134,7 +138,7 @@ void WorldEditorScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) // if ((!m_editedSelectedItems) && (m_mode != WorldEditorScene::SelectMode)) if ((!m_editedSelectedItems && m_selectedItems.isEmpty()) || - (!calcBoundingShape(m_selectedItems).contains(mouseEvent->scenePos()))) + (!calcBoundingRect(m_selectedItems).contains(mouseEvent->scenePos()))) { updatePickSelection(mouseEvent->scenePos()); m_firstSelection = true; @@ -190,29 +194,38 @@ void WorldEditorScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) } case WorldEditorScene::RotateMode: { - QRectF pivot = calcBoundingRect(m_selectedItems); + QPointF pivot = calcBoundingRect(m_selectedItems).center(); // Caluculate angle between two line - QLineF firstLine(pivot.center(), mouseEvent->lastScenePos()); - QLineF secondLine(pivot.center(), mouseEvent->scenePos()); + QLineF firstLine(pivot, mouseEvent->lastScenePos()); + QLineF secondLine(pivot, mouseEvent->scenePos()); qreal angle = secondLine.angleTo(firstLine); Q_FOREACH(QGraphicsItem *item, m_selectedItems) { - qgraphicsitem_cast(item)->rotateOn(pivot.center(), angle); + qgraphicsitem_cast(item)->rotateOn(pivot, angle); } break; } case WorldEditorScene::ScaleMode: { - // float scale = (_SelectionMin.x - _SelectionMax.x + _SelectionMax.y - _SelectionMin.y) * SCALE_PER_PIXEL + 1.f; - // moveAction->setScale (std::max (0.001f, scale), _MainFrame->getTransformMode ()==CMainFrame::Scale, radius); - // TODO: perfomance - QRectF pivot = calcBoundingRect(m_selectedItems); + QPointF pivot = calcBoundingRect(m_selectedItems).center(); + + // Calculate scale factor + if (offset.x() > 0) + offset.setX(1.0 + (offset.x() / 5000)); + else + offset.setX(1.0 / (1.0 + (-offset.x() / 5000))); + + if (offset.y() < 0) + offset.setY(1.0 + (-offset.y() / 5000)); + else + offset.setY(1.0 / (1.0 + (offset.y() / 5000))); + Q_FOREACH(QGraphicsItem *item, m_selectedItems) { - qgraphicsitem_cast(item)->scaleOn(pivot.center(), offset); + qgraphicsitem_cast(item)->scaleOn(pivot, offset); } break; } @@ -240,6 +253,51 @@ void WorldEditorScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent) if (mouseEvent->button() != Qt::LeftButton) return; + if (m_editedSelectedItems) + { + switch (m_mode) + { + case WorldEditorScene::SelectMode: + break; + + case WorldEditorScene::MoveMode: + { + QPointF offset = mouseEvent->scenePos() - m_firstPick; + + m_undoStack->push(new MoveWorldItemsCommand(m_selectedItems, offset, m_model)); + break; + } + case WorldEditorScene::RotateMode: + { + QPointF pivot = calcBoundingRect(m_selectedItems).center(); + + // Caluculate angle between two line + QLineF firstLine(pivot, m_firstPick); + QLineF secondLine(pivot, mouseEvent->scenePos()); + qreal angle = secondLine.angleTo(firstLine); + + m_undoStack->push(new RotateWorldItemsCommand(m_selectedItems, angle, pivot, m_model)); + break; + } + case WorldEditorScene::ScaleMode: + { + QPointF pivot = calcBoundingRect(m_selectedItems).center(); + QPointF offset = mouseEvent->scenePos() - m_firstPick; + + // Calculate scale factor + offset.setX(1.0 + (offset.x() / 5000)); + offset.setY(1.0 + (-offset.y() / 5000)); + + m_undoStack->push(new ScaleWorldItemsCommand(m_selectedItems, offset, pivot, m_model)); + break; + } + case WorldEditorScene::TurnMode: + break; + case WorldEditorScene::RadiusMode: + break; + }; + } + if ((m_selectionArea.left() != 0) && (m_selectionArea.right() != 0)) { QList listItems; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h index b97b9672c..defd59651 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h @@ -19,16 +19,17 @@ // Project includes #include "world_editor_global.h" -#include "world_editor_scene_item.h" #include "../landscape_editor/landscape_scene_base.h" // NeL includes // Qt includes +#include namespace WorldEditor { +class PrimitivesTreeModel; /* @class WorldEditorScene @@ -50,7 +51,8 @@ public: RadiusMode }; - WorldEditorScene(int sizeCell = 160, QObject *parent = 0); + WorldEditorScene(int sizeCell, PrimitivesTreeModel *model, + QUndoStack *undoStack, QObject *parent = 0); virtual ~WorldEditorScene(); QGraphicsItem *addWorldItemPoint(const QPointF &point, const float angle); @@ -91,6 +93,8 @@ private: uint m_lastPickedPrimitive; ModeEdit m_mode; bool m_editMode; + QUndoStack *m_undoStack; + PrimitivesTreeModel *m_model; }; } /* namespace WorldEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.cpp index d428aed51..31f63dc05 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.cpp @@ -378,7 +378,7 @@ void WorldItemPoint::rotateOn(const QPointF &pivot, const qreal deltaAngle) setPos(rotatedPolygon.boundingRect().center()); } -void WorldItemPoint::scaleOn(const QPointF &pivot, const QPointF &offset) +void WorldItemPoint::scaleOn(const QPointF &pivot, const QPointF &factor) { prepareGeometryChange(); @@ -389,7 +389,7 @@ void WorldItemPoint::scaleOn(const QPointF &pivot, const QPointF &offset) scaledPolygon.translate(-pivot); QTransform trans; - trans = trans.scale(1.0 + (offset.x() / 5000), 1.0 + (-offset.y() / 5000)); + trans = trans.scale(factor.x(), factor.y()); scaledPolygon = trans.map(scaledPolygon); scaledPolygon.translate(pivot); @@ -485,7 +485,7 @@ void WorldItemPath::rotateOn(const QPointF &pivot, const qreal deltaAngle) m_polygon.translate(pivot); } -void WorldItemPath::scaleOn(const QPointF &pivot, const QPointF &offset) +void WorldItemPath::scaleOn(const QPointF &pivot, const QPointF &factor) { prepareGeometryChange(); @@ -493,7 +493,7 @@ void WorldItemPath::scaleOn(const QPointF &pivot, const QPointF &offset) scaledPolygon.translate(-pivot); QTransform trans; - trans = trans.scale(1.0 + (offset.x() / 5000), 1.0 + (-offset.y() / 5000)); + trans = trans.scale(factor.x(), factor.y()); m_polygon = trans.map(scaledPolygon); m_polygon.translate(pivot); @@ -590,7 +590,7 @@ void WorldItemZone::rotateOn(const QPointF &pivot, const qreal deltaAngle) m_polygon.translate(pivot); } -void WorldItemZone::scaleOn(const QPointF &pivot, const QPointF &offset) +void WorldItemZone::scaleOn(const QPointF &pivot, const QPointF &factor) { prepareGeometryChange(); @@ -598,7 +598,7 @@ void WorldItemZone::scaleOn(const QPointF &pivot, const QPointF &offset) scaledPolygon.translate(-pivot); QTransform trans; - trans = trans.scale(1.0 + (offset.x() / 5000), 1.0 + (-offset.y() / 5000)); + trans = trans.scale(factor.x(), factor.y()); m_polygon = trans.map(scaledPolygon); m_polygon.translate(pivot); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h index 6c144518c..6f1669786 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h @@ -131,7 +131,7 @@ public: virtual void moveOn(const QPointF &offset) = 0; virtual void rotateOn(const QPointF &pivot, const qreal deltaAngle) = 0; // TODO: add modes: IgnoreAspectRatio, KeepAspectRatio - virtual void scaleOn(const QPointF &pivot, const QPointF &offset) = 0; + virtual void scaleOn(const QPointF &pivot, const QPointF &factor) = 0; virtual void turnOn(const QPointF &offset) = 0; virtual void radiusOn(const qreal radius) = 0; @@ -152,7 +152,7 @@ public: virtual void moveOn(const QPointF &offset); virtual void rotateOn(const QPointF &pivot, const qreal deltaAngle); - virtual void scaleOn(const QPointF &pivot, const QPointF &offset); + virtual void scaleOn(const QPointF &pivot, const QPointF &factor); virtual void turnOn(const QPointF &offset); virtual void radiusOn(const qreal radius); @@ -188,7 +188,7 @@ public: virtual void moveOn(const QPointF &offset); virtual void rotateOn(const QPointF &pivot, const qreal deltaAngle); - virtual void scaleOn(const QPointF &pivot, const QPointF &offset); + virtual void scaleOn(const QPointF &pivot, const QPointF &factor); virtual void turnOn(const QPointF &offset); virtual void radiusOn(const qreal radius); @@ -216,7 +216,7 @@ public: virtual void moveOn(const QPointF &offset); virtual void rotateOn(const QPointF &pivot, const qreal deltaAngle); - virtual void scaleOn(const QPointF &pivot, const QPointF &offset); + virtual void scaleOn(const QPointF &pivot, const QPointF &factor); virtual void turnOn(const QPointF &offset); virtual void radiusOn(const qreal radius); @@ -234,4 +234,6 @@ protected: } /* namespace WorldEditor */ +Q_DECLARE_METATYPE(WorldEditor::AbstractWorldItem *) + #endif // WORLD_EDITOR_SCENE_ITEM_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp index 52c4cd460..fb0f1463d 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp @@ -50,12 +50,20 @@ WorldEditorWindow::WorldEditorWindow(QWidget *parent) m_ui.setupUi(this); m_undoStack = new QUndoStack(this); - m_worldEditorScene = new WorldEditorScene(NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig->CellSize, this); + m_primitivesModel = new PrimitivesTreeModel(this); + + m_worldEditorScene = new WorldEditorScene(Utils::ligoConfig()->CellSize, m_primitivesModel, m_undoStack, this); m_zoneBuilderBase = new LandscapeEditor::ZoneBuilderBase(m_worldEditorScene); m_worldEditorScene->setZoneBuilder(m_zoneBuilderBase); m_ui.graphicsView->setScene(m_worldEditorScene); - //m_ui.graphicsView->setVisibleText(false); + m_ui.graphicsView->setVisibleText(false); + + m_ui.treePrimitivesView->setModel(m_primitivesModel); + // TODO: ? + m_ui.treePrimitivesView->setUndoStack(m_undoStack); + m_ui.treePrimitivesView->setZoneBuilder(m_zoneBuilderBase); + m_ui.treePrimitivesView->setWorldScene(m_worldEditorScene); QActionGroup *sceneModeGroup = new QActionGroup(this); sceneModeGroup->addAction(m_ui.selectAction); @@ -69,14 +77,6 @@ WorldEditorWindow::WorldEditorWindow(QWidget *parent) m_ui.newWorldEditAction->setIcon(QIcon(Core::Constants::ICON_NEW)); m_ui.saveWorldEditAction->setIcon(QIcon(Core::Constants::ICON_SAVE)); - m_primitivesModel = new PrimitivesTreeModel(this); - m_ui.treePrimitivesView->setModel(m_primitivesModel); - - // TODO: ? - m_ui.treePrimitivesView->setUndoStack(m_undoStack); - m_ui.treePrimitivesView->setZoneBuilder(m_zoneBuilderBase); - m_ui.treePrimitivesView->setWorldScene(m_worldEditorScene); - createMenus(); createToolBars(); readSettings(); From f4d699c5348cd3943cab6f3220f3e8b2e3350d46 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Thu, 11 Aug 2011 14:05:06 +0300 Subject: [PATCH 51/89] Fixed: #1302 Fixed undo/redo zoom items. --HG-- branch : gsoc2011-worldeditorqt --- .../src/plugins/world_editor/world_editor_scene.cpp | 11 +++++------ .../src/plugins/world_editor/world_editor_scene.h | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp index f722bea25..6fba9f628 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp @@ -160,6 +160,7 @@ void WorldEditorScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) case WorldEditorScene::RotateMode: break; case WorldEditorScene::ScaleMode: + m_scaleFactor = QPointF(1.0, 1.0); break; case WorldEditorScene::TurnMode: break; @@ -223,6 +224,9 @@ void WorldEditorScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) else offset.setY(1.0 / (1.0 + (offset.y() / 5000))); + m_scaleFactor.setX(offset.x() * m_scaleFactor.x()); + m_scaleFactor.setY(offset.y() * m_scaleFactor.y()); + Q_FOREACH(QGraphicsItem *item, m_selectedItems) { qgraphicsitem_cast(item)->scaleOn(pivot, offset); @@ -282,13 +286,8 @@ void WorldEditorScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent) case WorldEditorScene::ScaleMode: { QPointF pivot = calcBoundingRect(m_selectedItems).center(); - QPointF offset = mouseEvent->scenePos() - m_firstPick; - - // Calculate scale factor - offset.setX(1.0 + (offset.x() / 5000)); - offset.setY(1.0 + (-offset.y() / 5000)); + m_undoStack->push(new ScaleWorldItemsCommand(m_selectedItems, m_scaleFactor, pivot, m_model)); - m_undoStack->push(new ScaleWorldItemsCommand(m_selectedItems, offset, pivot, m_model)); break; } case WorldEditorScene::TurnMode: diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h index defd59651..408ba99b6 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h @@ -85,7 +85,7 @@ private: QPen m_pen1, m_pen2; QBrush m_brush1, m_brush2; - QPointF m_firstPick; + QPointF m_firstPick, m_scaleFactor; QRectF m_selectionArea; qreal m_firstPickX, m_firstPickY; QList m_selectedItems; From e39cc48a3af6648b3f501fbcc8e706bc049ffc05 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Thu, 11 Aug 2011 14:14:56 +0300 Subject: [PATCH 52/89] Fixed: #1302 Fixed crash program. --HG-- branch : gsoc2011-worldeditorqt --- .../src/plugins/world_editor/world_editor_actions.cpp | 2 +- .../src/plugins/world_editor/world_editor_scene.cpp | 9 +++++++++ .../src/plugins/world_editor/world_editor_scene.h | 2 ++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp index c6ed1ee3e..440382b15 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp @@ -121,7 +121,7 @@ void removeGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *mode { QGraphicsItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); if (item != 0) - delete item; + scene->removeWorldItem(item); break; } } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp index 6fba9f628..7e2ac9c20 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp @@ -80,6 +80,15 @@ QGraphicsItem *WorldEditorScene::addWorldItemZone(const QPolygonF &polygon) return item; } +void WorldEditorScene::removeWorldItem(QGraphicsItem *item) +{ + updateSelectedItems(true); + m_selectedItems.clear(); + m_editedSelectedItems = false; + m_firstSelection = false; + delete item; +} + void WorldEditorScene::setModeEdit(WorldEditorScene::ModeEdit mode) { if (mode == WorldEditorScene::SelectMode) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h index 408ba99b6..aa813c5c5 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h @@ -59,6 +59,8 @@ public: QGraphicsItem *addWorldItemPath(const QPolygonF &polyline); QGraphicsItem *addWorldItemZone(const QPolygonF &polygon); + void removeWorldItem(QGraphicsItem *item); + void setModeEdit(WorldEditorScene::ModeEdit mode); WorldEditorScene::ModeEdit editMode() const; From 8116d76d1ed1d9a84c3ab31b3e39de7ca1a64fc7 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Thu, 11 Aug 2011 22:58:45 +0300 Subject: [PATCH 53/89] Changed: #1302 Added the turn undo command. --HG-- branch : gsoc2011-worldeditorqt --- .../colors_workspace_settings_page.ui | 44 ------- .../world_editor/world_editor_actions.cpp | 108 +++++++++++++++--- .../world_editor/world_editor_actions.h | 25 +++- .../world_editor/world_editor_plugin.cpp | 4 +- .../world_editor/world_editor_scene.cpp | 59 +++++----- .../plugins/world_editor/world_editor_scene.h | 11 +- .../world_editor/world_editor_scene_item.cpp | 52 +++++++-- .../world_editor/world_editor_scene_item.h | 25 ++-- .../world_editor/world_editor_window.ui | 2 +- 9 files changed, 213 insertions(+), 117 deletions(-) delete mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/colors_workspace_settings_page.ui diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/colors_workspace_settings_page.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/colors_workspace_settings_page.ui deleted file mode 100644 index de6e77901..000000000 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/colors_workspace_settings_page.ui +++ /dev/null @@ -1,44 +0,0 @@ - - - WorldEditorSettingsPage - - - - 0 - 0 - 329 - 239 - - - - Form - - - - - - Colors - - - - - - - - Qt::Vertical - - - - 20 - 0 - - - - - - - - - - - diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp index 440382b15..780ea47a9 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp @@ -52,13 +52,14 @@ void addNewGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *mode { NLLIGO::IPrimitive *primitive = node->primitive(); NLLIGO::CPrimVector *vec = 0; - QGraphicsItem *item; + AbstractWorldItem *item = 0; switch (node->primitiveClass()->Type) { case NLLIGO::CPrimitiveClass::Point: { vec = primitive->getPrimVector(); - item = scene->addWorldItemPoint(QPointF(vec->x, -vec->y + cellSize), 0); + NLLIGO::CPrimPoint *primPoint = static_cast(primitive); + item = scene->addWorldItemPoint(QPointF(vec->x, -vec->y + cellSize), primPoint->Angle); break; } case NLLIGO::CPrimitiveClass::Path: @@ -91,12 +92,44 @@ void addNewGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *mode break; } } + + if (item != 0) + { + // Get color from world_editor_classes.xml + NLMISC::CRGBA color = Utils::ligoConfig()->getPrimitiveColor(*primitive); + + /* + // Configurations (from world_editor_primitive_configuration.xml) + const std::vector &configurations = Utils::ligoConfig()->getPrimitiveConfiguration(); + + // Look for the configuration + sint search = 0; + bool colorFound = false; + while ((search = theApp.getActiveConfiguration (*primitive, search)) != -1) + { + // Configuration activated ? + if (theApp.Configurations[search].Activated) + { + colorFound = true; + mainColor = configurations[search].Color; + break; + } + search++; + } + + // try to get the primitive color ? + //if (!colorFound)*/ + primitive->getPropertyByName ("Color", color); + + item->setColor(QColor(color.R, color.G, color.B)); + } + QVariant variantNode; variantNode.setValue(node); item->setData(Constants::WORLD_EDITOR_NODE, variantNode); QVariant graphicsData; - graphicsData.setValue(item); + graphicsData.setValue(item); node->setData(Constants::GRAPHICS_DATA_QT4_2D, graphicsData); } @@ -119,7 +152,7 @@ void removeGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *mode case NLLIGO::CPrimitiveClass::Path: case NLLIGO::CPrimitiveClass::Zone: { - QGraphicsItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); + QGraphicsItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); if (item != 0) scene->removeWorldItem(item); break; @@ -363,8 +396,8 @@ void MoveWorldItemsCommand::undo() for (int i = 0; i < m_listPaths.count(); ++i) { Node *node = m_model->pathToNode(m_listPaths.at(i)); - QGraphicsItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); - qgraphicsitem_cast(item)->moveOn(-m_offset); + AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); + item->moveOn(-m_offset); } } @@ -375,14 +408,14 @@ void MoveWorldItemsCommand::redo() for (int i = 0; i < m_listPaths.count(); ++i) { Node *node = m_model->pathToNode(m_listPaths.at(i)); - QGraphicsItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); - qgraphicsitem_cast(item)->moveOn(m_offset); + AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); + item->moveOn(m_offset); } } m_firstRun = false; } -RotateWorldItemsCommand::RotateWorldItemsCommand(const QList &items, const qreal &angle, +RotateWorldItemsCommand::RotateWorldItemsCommand(const QList &items, const qreal angle, const QPointF &pivot, PrimitivesTreeModel *model, QUndoCommand *parent) : QUndoCommand(parent), m_listPaths(graphicsItemsToPaths(items, model)), @@ -391,7 +424,7 @@ RotateWorldItemsCommand::RotateWorldItemsCommand(const QList &i m_model(model), m_firstRun(true) { - setText("Rotate item(s)"); + setText(QString("Rotate item(s) %1").arg(m_angle)); } RotateWorldItemsCommand::~RotateWorldItemsCommand() @@ -403,8 +436,8 @@ void RotateWorldItemsCommand::undo() for (int i = 0; i < m_listPaths.count(); ++i) { Node *node = m_model->pathToNode(m_listPaths.at(i)); - QGraphicsItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); - qgraphicsitem_cast(item)->rotateOn(m_pivot, -m_angle); + AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); + item->rotateOn(m_pivot, -m_angle); } } @@ -415,8 +448,8 @@ void RotateWorldItemsCommand::redo() for (int i = 0; i < m_listPaths.count(); ++i) { Node *node = m_model->pathToNode(m_listPaths.at(i)); - QGraphicsItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); - qgraphicsitem_cast(item)->rotateOn(m_pivot, m_angle); + AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); + item->rotateOn(m_pivot, m_angle); } } m_firstRun = false; @@ -444,8 +477,8 @@ void ScaleWorldItemsCommand::undo() for (int i = 0; i < m_listPaths.count(); ++i) { Node *node = m_model->pathToNode(m_listPaths.at(i)); - QGraphicsItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); - qgraphicsitem_cast(item)->scaleOn(m_pivot, m_invertFactor); + AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); + item->scaleOn(m_pivot, m_invertFactor); } } @@ -456,8 +489,47 @@ void ScaleWorldItemsCommand::redo() for (int i = 0; i < m_listPaths.count(); ++i) { Node *node = m_model->pathToNode(m_listPaths.at(i)); - QGraphicsItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); - qgraphicsitem_cast(item)->scaleOn(m_pivot, m_factor); + AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); + item->scaleOn(m_pivot, m_factor); + } + } + m_firstRun = false; +} + +TurnWorldItemsCommand::TurnWorldItemsCommand(const QList &items, const qreal angle, + PrimitivesTreeModel *model, QUndoCommand *parent) + : QUndoCommand(parent), + m_listPaths(graphicsItemsToPaths(items, model)), + m_angle(angle), + m_model(model), + m_firstRun(true) +{ + setText(QString("Turn item(s) %1").arg(m_angle)); +} + +TurnWorldItemsCommand::~TurnWorldItemsCommand() +{ +} + +void TurnWorldItemsCommand::undo() +{ + for (int i = 0; i < m_listPaths.count(); ++i) + { + Node *node = m_model->pathToNode(m_listPaths.at(i)); + AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); + item->turnOn(-m_angle); + } +} + +void TurnWorldItemsCommand::redo() +{ + if (!m_firstRun) + { + for (int i = 0; i < m_listPaths.count(); ++i) + { + Node *node = m_model->pathToNode(m_listPaths.at(i)); + AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); + item->turnOn(m_angle); } } m_firstRun = false; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h index 7fd2015e0..2eda788b4 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h @@ -172,7 +172,7 @@ private: class RotateWorldItemsCommand: public QUndoCommand { public: - RotateWorldItemsCommand(const QList &items, const qreal &angle, + RotateWorldItemsCommand(const QList &items, const qreal angle, const QPointF &pivot, PrimitivesTreeModel *model, QUndoCommand *parent = 0); virtual ~RotateWorldItemsCommand(); @@ -210,6 +210,29 @@ private: bool m_firstRun; }; +/** +@class TurnWorldItemsCommand +@brief +@details +*/ +class TurnWorldItemsCommand: public QUndoCommand +{ +public: + TurnWorldItemsCommand(const QList &items, const qreal angle, + PrimitivesTreeModel *model, QUndoCommand *parent = 0); + virtual ~TurnWorldItemsCommand(); + + virtual void undo(); + virtual void redo(); +private: + + const QList m_listPaths; + const qreal m_angle; + PrimitivesTreeModel *const m_model; + bool m_firstRun; +}; + + } /* namespace WorldEditor */ #endif // WORLD_EDITOR_ACTIONS_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_plugin.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_plugin.cpp index 051d403ea..8699bfb67 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_plugin.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_plugin.cpp @@ -77,8 +77,8 @@ bool WorldEditorPlugin::initialize(ExtensionSystem::IPluginManager *pluginManage // Reset m_ligoConfig.resetPrimitiveConfiguration (); - // Load - m_ligoConfig.readPrimitiveClass ("world_editor_primitive_configuration.xml", true); + // TODO: get file names! from settings + m_ligoConfig.readPrimitiveClass("world_editor_primitive_configuration.xml", true); addAutoReleasedObject(new WorldEditorContext(this)); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp index 7e2ac9c20..d02c047b1 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp @@ -59,21 +59,21 @@ WorldEditorScene::~WorldEditorScene() { } -QGraphicsItem *WorldEditorScene::addWorldItemPoint(const QPointF &point, const float angle) +AbstractWorldItem *WorldEditorScene::addWorldItemPoint(const QPointF &point, const float angle) { WorldItemPoint *item = new WorldItemPoint(point, angle); addItem(item); return item; } -QGraphicsItem *WorldEditorScene::addWorldItemPath(const QPolygonF &polyline) +AbstractWorldItem *WorldEditorScene::addWorldItemPath(const QPolygonF &polyline) { WorldItemPath *item = new WorldItemPath(polyline); addItem(item); return item; } -QGraphicsItem *WorldEditorScene::addWorldItemZone(const QPolygonF &polygon) +AbstractWorldItem *WorldEditorScene::addWorldItemZone(const QPolygonF &polygon) { WorldItemZone *item = new WorldItemZone(polygon); addItem(item); @@ -167,11 +167,16 @@ void WorldEditorScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) break; } case WorldEditorScene::RotateMode: + m_angle = 0; + m_pivot = calcBoundingRect(m_selectedItems).center(); break; case WorldEditorScene::ScaleMode: m_scaleFactor = QPointF(1.0, 1.0); + m_pivot = calcBoundingRect(m_selectedItems).center(); break; case WorldEditorScene::TurnMode: + m_angle = 0; + m_pivot = calcBoundingRect(m_selectedItems).center(); break; case WorldEditorScene::RadiusMode: break; @@ -204,24 +209,21 @@ void WorldEditorScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) } case WorldEditorScene::RotateMode: { - QPointF pivot = calcBoundingRect(m_selectedItems).center(); - // Caluculate angle between two line - QLineF firstLine(pivot, mouseEvent->lastScenePos()); - QLineF secondLine(pivot, mouseEvent->scenePos()); + QLineF firstLine(m_pivot, mouseEvent->lastScenePos()); + QLineF secondLine(m_pivot, mouseEvent->scenePos()); qreal angle = secondLine.angleTo(firstLine); + m_angle += angle; + Q_FOREACH(QGraphicsItem *item, m_selectedItems) { - qgraphicsitem_cast(item)->rotateOn(pivot, angle); + qgraphicsitem_cast(item)->rotateOn(m_pivot, angle); } break; } case WorldEditorScene::ScaleMode: { - // TODO: perfomance - QPointF pivot = calcBoundingRect(m_selectedItems).center(); - // Calculate scale factor if (offset.x() > 0) offset.setX(1.0 + (offset.x() / 5000)); @@ -238,12 +240,26 @@ void WorldEditorScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) Q_FOREACH(QGraphicsItem *item, m_selectedItems) { - qgraphicsitem_cast(item)->scaleOn(pivot, offset); + qgraphicsitem_cast(item)->scaleOn(m_pivot, offset); } break; } case WorldEditorScene::TurnMode: + { + // Caluculate angle between two line + QLineF firstLine(m_pivot, mouseEvent->lastScenePos()); + QLineF secondLine(m_pivot, mouseEvent->scenePos()); + qreal angle = secondLine.angleTo(firstLine); + + m_angle += angle; + + Q_FOREACH(QGraphicsItem *item, m_selectedItems) + { + qgraphicsitem_cast(item)->turnOn(angle); + } + break; + } case WorldEditorScene::RadiusMode: break; }; @@ -276,30 +292,17 @@ void WorldEditorScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent) case WorldEditorScene::MoveMode: { QPointF offset = mouseEvent->scenePos() - m_firstPick; - m_undoStack->push(new MoveWorldItemsCommand(m_selectedItems, offset, m_model)); break; } case WorldEditorScene::RotateMode: - { - QPointF pivot = calcBoundingRect(m_selectedItems).center(); - - // Caluculate angle between two line - QLineF firstLine(pivot, m_firstPick); - QLineF secondLine(pivot, mouseEvent->scenePos()); - qreal angle = secondLine.angleTo(firstLine); - - m_undoStack->push(new RotateWorldItemsCommand(m_selectedItems, angle, pivot, m_model)); + m_undoStack->push(new RotateWorldItemsCommand(m_selectedItems, m_angle, m_pivot, m_model)); break; - } case WorldEditorScene::ScaleMode: - { - QPointF pivot = calcBoundingRect(m_selectedItems).center(); - m_undoStack->push(new ScaleWorldItemsCommand(m_selectedItems, m_scaleFactor, pivot, m_model)); - + m_undoStack->push(new ScaleWorldItemsCommand(m_selectedItems, m_scaleFactor, m_pivot, m_model)); break; - } case WorldEditorScene::TurnMode: + m_undoStack->push(new TurnWorldItemsCommand(m_selectedItems, m_angle, m_model)); break; case WorldEditorScene::RadiusMode: break; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h index aa813c5c5..265067469 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h @@ -30,6 +30,7 @@ namespace WorldEditor { class PrimitivesTreeModel; +class AbstractWorldItem; /* @class WorldEditorScene @@ -55,9 +56,9 @@ public: QUndoStack *undoStack, QObject *parent = 0); virtual ~WorldEditorScene(); - QGraphicsItem *addWorldItemPoint(const QPointF &point, const float angle); - QGraphicsItem *addWorldItemPath(const QPolygonF &polyline); - QGraphicsItem *addWorldItemZone(const QPolygonF &polygon); + AbstractWorldItem *addWorldItemPoint(const QPointF &point, const float angle); + AbstractWorldItem *addWorldItemPath(const QPolygonF &polyline); + AbstractWorldItem *addWorldItemZone(const QPolygonF &polygon); void removeWorldItem(QGraphicsItem *item); @@ -87,9 +88,9 @@ private: QPen m_pen1, m_pen2; QBrush m_brush1, m_brush2; - QPointF m_firstPick, m_scaleFactor; + QPointF m_firstPick, m_scaleFactor, m_pivot; QRectF m_selectionArea; - qreal m_firstPickX, m_firstPickY; + qreal m_firstPickX, m_firstPickY, m_angle; QList m_selectedItems; bool m_editedSelectedItems, m_firstSelection; uint m_lastPickedPrimitive; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.cpp index 31f63dc05..249ad15e3 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.cpp @@ -322,9 +322,9 @@ int AbstractWorldItem::type() const return Type; } -WorldItemPoint::WorldItemPoint(const QPointF &point, const float angle, QGraphicsItem *parent) +WorldItemPoint::WorldItemPoint(const QPointF &point, const qreal angle, QGraphicsItem *parent) : AbstractWorldItem(parent), - m_angle(angle) + m_angle((2 * NLMISC::Pi - angle) * 180 / NLMISC::Pi) { setZValue(WORLD_POINT_LAYER); @@ -343,7 +343,7 @@ WorldItemPoint::WorldItemPoint(const QPointF &point, const float angle, QGraphic m_brush.setColor(QColor(255, 100, 10)); m_brush.setStyle(Qt::SolidPattern); - m_selectedBrush.setColor(QColor(0, 255, 0)); + m_selectedBrush.setColor(Qt::NoPen); m_selectedBrush.setStyle(Qt::SolidPattern); //setFlag(ItemIsSelectable); @@ -396,14 +396,21 @@ void WorldItemPoint::scaleOn(const QPointF &pivot, const QPointF &factor) setPos(scaledPolygon.boundingRect().center()); } -void WorldItemPoint::turnOn(const QPointF &offset) +void WorldItemPoint::turnOn(const qreal angle) { + m_angle += angle; + update(); } void WorldItemPoint::radiusOn(const qreal radius) { } +void WorldItemPoint::setColor(const QColor &color) +{ + m_brush.setColor(color); +} + QPainterPath WorldItemPoint::shape() const { QPainterPath path; @@ -435,6 +442,14 @@ void WorldItemPoint::paint(QPainter *painter, const QStyleOptionGraphicsItem *op } painter->drawRect(m_rect); + + painter->setPen(Qt::red); + + painter->rotate(m_angle); + + painter->drawLine(0, 0, SIZE_ARROW, 0); + painter->drawLine(SIZE_ARROW - 2, -2, SIZE_ARROW, 0); + painter->drawLine(SIZE_ARROW - 2, 2, SIZE_ARROW, 0); } QVariant WorldItemPoint::itemChange(GraphicsItemChange change, const QVariant &value) @@ -453,10 +468,10 @@ WorldItemPath::WorldItemPath(const QPolygonF &polygon, QGraphicsItem *parent) setZValue(WORLD_PATH_LAYER); - m_pen.setColor(QColor(0, 0, 0)); + m_pen.setColor(Qt::black); m_pen.setWidth(5); - m_selectedPen.setColor(QColor(255, 0, 0)); + m_selectedPen.setColor(Qt::white); m_selectedPen.setWidth(5); } @@ -499,7 +514,7 @@ void WorldItemPath::scaleOn(const QPointF &pivot, const QPointF &factor) m_polygon.translate(pivot); } -void WorldItemPath::turnOn(const QPointF &offset) +void WorldItemPath::turnOn(const qreal angle) { } @@ -507,6 +522,11 @@ void WorldItemPath::radiusOn(const qreal radius) { } +void WorldItemPath::setColor(const QColor &color) +{ + m_pen.setColor(color); +} + QPainterPath WorldItemPath::shape() const { QPainterPath path; @@ -555,13 +575,13 @@ WorldItemZone::WorldItemZone(const QPolygonF &polygon, QGraphicsItem *parent) m_pen.setColor(QColor(20, 100, 255)); m_pen.setWidth(0); - m_selectedPen.setColor(QColor(255, 0, 0)); + m_selectedPen.setColor(Qt::white); m_selectedPen.setWidth(0); - m_brush.setColor(QColor(20, 100, 255, 28)); + m_brush.setColor(QColor(20, 100, 255, TRANSPARENCY)); m_brush.setStyle(Qt::SolidPattern); - m_selectedBrush.setColor(QColor(255, 0, 0, 128)); + m_selectedBrush.setColor(QColor(255, 255, 255, 100)); m_selectedBrush.setStyle(Qt::SolidPattern); } @@ -604,7 +624,7 @@ void WorldItemZone::scaleOn(const QPointF &pivot, const QPointF &factor) m_polygon.translate(pivot); } -void WorldItemZone::turnOn(const QPointF &offset) +void WorldItemZone::turnOn(const qreal angle) { } @@ -612,6 +632,16 @@ void WorldItemZone::radiusOn(const qreal radius) { } +void WorldItemZone::setColor(const QColor &color) +{ + m_pen.setColor(color); + + QColor brushColor(color); + brushColor.setAlpha(TRANSPARENCY); + + m_brush.setColor(brushColor); +} + QRectF WorldItemZone::boundingRect() const { return m_polygon.boundingRect(); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h index 6f1669786..cdc9691b4 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h @@ -45,6 +45,7 @@ const int WORLD_PATH_LAYER = 200; const int MIDDLE_POINT_LAYER = 201; const int EDGE_POINT_LAYER = 201; +const int SIZE_ARROW = 20; /* // Deprecated class GraphicsItemNode: public QGraphicsObject @@ -132,9 +133,11 @@ public: virtual void rotateOn(const QPointF &pivot, const qreal deltaAngle) = 0; // TODO: add modes: IgnoreAspectRatio, KeepAspectRatio virtual void scaleOn(const QPointF &pivot, const QPointF &factor) = 0; - virtual void turnOn(const QPointF &offset) = 0; + virtual void turnOn(const qreal angle) = 0; virtual void radiusOn(const qreal radius) = 0; + virtual void setColor(const QColor &color) = 0; + // Enable the use of qgraphicsitem_cast with this item. int type() const; }; @@ -147,15 +150,17 @@ public: class WorldItemPoint: public AbstractWorldItem { public: - WorldItemPoint(const QPointF &point, const float angle, QGraphicsItem *parent = 0); + WorldItemPoint(const QPointF &point, const qreal angle, QGraphicsItem *parent = 0); virtual ~WorldItemPoint(); virtual void moveOn(const QPointF &offset); virtual void rotateOn(const QPointF &pivot, const qreal deltaAngle); virtual void scaleOn(const QPointF &pivot, const QPointF &factor); - virtual void turnOn(const QPointF &offset); + virtual void turnOn(const qreal angle); virtual void radiusOn(const qreal radius); + virtual void setColor(const QColor &color); + virtual QRectF boundingRect() const; virtual QPainterPath shape() const; virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); @@ -166,13 +171,13 @@ protected: private: // TODO - static const int SIZE_POINT = 7; + static const int SIZE_POINT = 4; QPen m_pen, m_selectedPen; QBrush m_brush, m_selectedBrush; QRectF m_rect; - float m_angle; + qreal m_angle; }; /* @@ -189,9 +194,11 @@ public: virtual void moveOn(const QPointF &offset); virtual void rotateOn(const QPointF &pivot, const qreal deltaAngle); virtual void scaleOn(const QPointF &pivot, const QPointF &factor); - virtual void turnOn(const QPointF &offset); + virtual void turnOn(const qreal angle); virtual void radiusOn(const qreal radius); + virtual void setColor(const QColor &color); + virtual QRectF boundingRect() const; virtual QPainterPath shape() const; virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); @@ -217,9 +224,11 @@ public: virtual void moveOn(const QPointF &offset); virtual void rotateOn(const QPointF &pivot, const qreal deltaAngle); virtual void scaleOn(const QPointF &pivot, const QPointF &factor); - virtual void turnOn(const QPointF &offset); + virtual void turnOn(const qreal angle); virtual void radiusOn(const qreal radius); + virtual void setColor(const QColor &color); + virtual QRectF boundingRect() const; virtual QPainterPath shape() const; virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); @@ -227,6 +236,8 @@ public: protected: virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value); + static const int TRANSPARENCY = 28; + QPen m_pen, m_selectedPen; QBrush m_brush, m_selectedBrush; QPolygonF m_polygon; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui index f5dc5f408..c556514b7 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui @@ -293,7 +293,7 @@ true - false + true From 14964373fb8f2a54cb26499dd536ff6b0b03e655 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Fri, 12 Aug 2011 13:38:13 +0300 Subject: [PATCH 54/89] Changed: #1302 Added drawing of circle for point primitive --HG-- branch : gsoc2011-worldeditorqt --- .../world_editor/world_editor_actions.cpp | 17 ++- .../world_editor/world_editor_scene.cpp | 7 +- .../plugins/world_editor/world_editor_scene.h | 3 +- .../world_editor/world_editor_scene_item.cpp | 126 ++++++++++-------- .../world_editor/world_editor_scene_item.h | 14 +- .../world_editor/world_editor_window.cpp | 23 +++- .../world_editor/world_editor_window.h | 1 + 7 files changed, 122 insertions(+), 69 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp index 780ea47a9..41de05f85 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp @@ -59,7 +59,18 @@ void addNewGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *mode { vec = primitive->getPrimVector(); NLLIGO::CPrimPoint *primPoint = static_cast(primitive); - item = scene->addWorldItemPoint(QPointF(vec->x, -vec->y + cellSize), primPoint->Angle); + + // Draw arrow ? + bool showArrow = node->primitiveClass()->ShowArrow; + + // Have a radius ? + std::string strRadius; + qreal radius = 0; + if (primitive->getPropertyByName ("radius", strRadius)) + radius = atof(strRadius.c_str()); + + item = scene->addWorldItemPoint(QPointF(vec->x, -vec->y + cellSize), + primPoint->Angle, radius, showArrow); break; } case NLLIGO::CPrimitiveClass::Path: @@ -397,7 +408,7 @@ void MoveWorldItemsCommand::undo() { Node *node = m_model->pathToNode(m_listPaths.at(i)); AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); - item->moveOn(-m_offset); + item->moveBy(-m_offset.x(), -m_offset.y()); } } @@ -409,7 +420,7 @@ void MoveWorldItemsCommand::redo() { Node *node = m_model->pathToNode(m_listPaths.at(i)); AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); - item->moveOn(m_offset); + item->moveBy(m_offset.x(), m_offset.y()); } } m_firstRun = false; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp index d02c047b1..b986d7c0c 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp @@ -59,9 +59,10 @@ WorldEditorScene::~WorldEditorScene() { } -AbstractWorldItem *WorldEditorScene::addWorldItemPoint(const QPointF &point, const float angle) +AbstractWorldItem *WorldEditorScene::addWorldItemPoint(const QPointF &point, const qreal angle, + const qreal radius, bool showArrow) { - WorldItemPoint *item = new WorldItemPoint(point, angle); + WorldItemPoint *item = new WorldItemPoint(point, angle, radius, showArrow); addItem(item); return item; } @@ -203,7 +204,7 @@ void WorldEditorScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) { Q_FOREACH(QGraphicsItem *item, m_selectedItems) { - qgraphicsitem_cast(item)->moveOn(offset); + item->moveBy(offset.x(), offset.y()); } break; } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h index 265067469..c7868b15a 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h @@ -56,7 +56,8 @@ public: QUndoStack *undoStack, QObject *parent = 0); virtual ~WorldEditorScene(); - AbstractWorldItem *addWorldItemPoint(const QPointF &point, const float angle); + AbstractWorldItem *addWorldItemPoint(const QPointF &point, const qreal angle, + const qreal radius, bool showArrow); AbstractWorldItem *addWorldItemPath(const QPolygonF &polyline); AbstractWorldItem *addWorldItemZone(const QPolygonF &polygon); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.cpp index 249ad15e3..0e65e6455 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.cpp @@ -322,9 +322,12 @@ int AbstractWorldItem::type() const return Type; } -WorldItemPoint::WorldItemPoint(const QPointF &point, const qreal angle, QGraphicsItem *parent) +WorldItemPoint::WorldItemPoint(const QPointF &point, const qreal angle, const qreal radius, + bool showArrow, QGraphicsItem *parent) : AbstractWorldItem(parent), - m_angle((2 * NLMISC::Pi - angle) * 180 / NLMISC::Pi) + m_angle((2 * NLMISC::Pi - angle) * 180 / NLMISC::Pi), + m_radius(radius), + m_showArrow(showArrow) { setZValue(WORLD_POINT_LAYER); @@ -335,17 +338,41 @@ WorldItemPoint::WorldItemPoint(const QPointF &point, const qreal angle, QGraphic m_rect.setCoords(-SIZE_POINT, -SIZE_POINT, SIZE_POINT, SIZE_POINT); m_pen.setColor(QColor(255, 100, 10)); - m_pen.setWidth(5); + //m_pen.setWidth(0); - m_selectedPen.setColor(QColor(0, 255, 0)); - m_selectedPen.setWidth(5); + m_selectedPen.setColor(Qt::white); + //m_selectedPen.setWidth(0); m_brush.setColor(QColor(255, 100, 10)); m_brush.setStyle(Qt::SolidPattern); - m_selectedBrush.setColor(Qt::NoPen); + m_selectedBrush.setColor(Qt::white); m_selectedBrush.setStyle(Qt::SolidPattern); + + if (m_radius != 0) + { + // Create circle + int segmentCount = 30; + QPointF circlePoint(m_radius, 0); + m_circle << circlePoint; + for (int i = 1; i < segmentCount + 1; ++i) + { + qreal angle = i * (2 * NLMISC::Pi / segmentCount); + circlePoint.setX(cos(angle) * m_radius); + circlePoint.setY(sin(angle) * m_radius); + m_circle << circlePoint; + } + } + + // Create arrow + if (showArrow) + { + m_arrow.push_back(QLine(0, 0, SIZE_ARROW, 0)); + m_arrow.push_back(QLine(SIZE_ARROW - 2, -2, SIZE_ARROW, 0)); + m_arrow.push_back(QLine(SIZE_ARROW - 2, 2, SIZE_ARROW, 0)); + } + //setFlag(ItemIsSelectable); } @@ -353,13 +380,6 @@ WorldItemPoint::~WorldItemPoint() { } -void WorldItemPoint::moveOn(const QPointF &offset) -{ - prepareGeometryChange(); - - setPos(pos() + offset); -} - void WorldItemPoint::rotateOn(const QPointF &pivot, const qreal deltaAngle) { prepareGeometryChange(); @@ -367,8 +387,8 @@ void WorldItemPoint::rotateOn(const QPointF &pivot, const qreal deltaAngle) QPolygonF rotatedPolygon(m_rect); // TODO - rotatedPolygon.translate(pos()); - rotatedPolygon.translate(-pivot); + rotatedPolygon.translate(pos() - pivot); + //rotatedPolygon.translate(-pivot); QTransform trans; trans = trans.rotate(deltaAngle); @@ -385,8 +405,8 @@ void WorldItemPoint::scaleOn(const QPointF &pivot, const QPointF &factor) QPolygonF scaledPolygon(m_rect); // TODO - scaledPolygon.translate(pos()); - scaledPolygon.translate(-pivot); + scaledPolygon.translate(pos() - pivot); + //scaledPolygon.translate(-pivot); QTransform trans; trans = trans.scale(factor.x(), factor.y()); @@ -408,6 +428,7 @@ void WorldItemPoint::radiusOn(const qreal radius) void WorldItemPoint::setColor(const QColor &color) { + m_pen.setColor(color); m_brush.setColor(color); } @@ -430,26 +451,26 @@ void WorldItemPoint::paint(QPainter *painter, const QStyleOptionGraphicsItem *op // Here comes the magic: //painter->setClipRect(option->exposedRect); - painter->setPen(Qt::NoPen); + painter->setPen(m_pen); + // Draw circle + // Draws artefacts with using opengl painter + // painter->drawEllipse(-m_radius / 2, -m_radius / 2, m_radius, m_radius); + painter->drawPolygon(m_circle); + + painter->rotate(m_angle); + + // Draw arrow + painter->drawLines(m_arrow); + + painter->setPen(Qt::NoPen); if (option->state & QStyle::State_Selected) - { painter->setBrush(m_selectedBrush); - } else - { painter->setBrush(m_brush); - } + // Draw point painter->drawRect(m_rect); - - painter->setPen(Qt::red); - - painter->rotate(m_angle); - - painter->drawLine(0, 0, SIZE_ARROW, 0); - painter->drawLine(SIZE_ARROW - 2, -2, SIZE_ARROW, 0); - painter->drawLine(SIZE_ARROW - 2, 2, SIZE_ARROW, 0); } QVariant WorldItemPoint::itemChange(GraphicsItemChange change, const QVariant &value) @@ -469,21 +490,20 @@ WorldItemPath::WorldItemPath(const QPolygonF &polygon, QGraphicsItem *parent) setZValue(WORLD_PATH_LAYER); m_pen.setColor(Qt::black); - m_pen.setWidth(5); + m_pen.setWidth(3); + m_pen.setJoinStyle(Qt::MiterJoin); m_selectedPen.setColor(Qt::white); - m_selectedPen.setWidth(5); -} + m_selectedPen.setWidth(3); + m_selectedPen.setJoinStyle(Qt::MiterJoin); -WorldItemPath::~WorldItemPath() -{ + QPointF center = m_polygon.boundingRect().center(); + m_polygon.translate(-center); + setPos(center); } -void WorldItemPath::moveOn(const QPointF &offset) +WorldItemPath::~WorldItemPath() { - prepareGeometryChange(); - - m_polygon.translate(offset); } void WorldItemPath::rotateOn(const QPointF &pivot, const qreal deltaAngle) @@ -491,13 +511,13 @@ void WorldItemPath::rotateOn(const QPointF &pivot, const qreal deltaAngle) prepareGeometryChange(); QPolygonF rotatedPolygon(m_polygon); - rotatedPolygon.translate(-pivot); + rotatedPolygon.translate(pos() - pivot); QTransform trans; trans = trans.rotate(deltaAngle); m_polygon = trans.map(rotatedPolygon); - m_polygon.translate(pivot); + m_polygon.translate(pivot - pos()); } void WorldItemPath::scaleOn(const QPointF &pivot, const QPointF &factor) @@ -505,13 +525,13 @@ void WorldItemPath::scaleOn(const QPointF &pivot, const QPointF &factor) prepareGeometryChange(); QPolygonF scaledPolygon(m_polygon); - scaledPolygon.translate(-pivot); + scaledPolygon.translate(pos() - pivot); QTransform trans; trans = trans.scale(factor.x(), factor.y()); m_polygon = trans.map(scaledPolygon); - m_polygon.translate(pivot); + m_polygon.translate(pivot - pos()); } void WorldItemPath::turnOn(const qreal angle) @@ -583,17 +603,14 @@ WorldItemZone::WorldItemZone(const QPolygonF &polygon, QGraphicsItem *parent) m_selectedBrush.setColor(QColor(255, 255, 255, 100)); m_selectedBrush.setStyle(Qt::SolidPattern); -} -WorldItemZone::~WorldItemZone() -{ + QPointF center = m_polygon.boundingRect().center(); + m_polygon.translate(-center); + setPos(center); } -void WorldItemZone::moveOn(const QPointF &offset) +WorldItemZone::~WorldItemZone() { - prepareGeometryChange(); - - m_polygon.translate(offset); } void WorldItemZone::rotateOn(const QPointF &pivot, const qreal deltaAngle) @@ -601,13 +618,13 @@ void WorldItemZone::rotateOn(const QPointF &pivot, const qreal deltaAngle) prepareGeometryChange(); QPolygonF rotatedPolygon(m_polygon); - rotatedPolygon.translate(-pivot); + rotatedPolygon.translate(pos() - pivot); QTransform trans; trans = trans.rotate(deltaAngle); m_polygon = trans.map(rotatedPolygon); - m_polygon.translate(pivot); + m_polygon.translate(pivot - pos()); } void WorldItemZone::scaleOn(const QPointF &pivot, const QPointF &factor) @@ -615,13 +632,14 @@ void WorldItemZone::scaleOn(const QPointF &pivot, const QPointF &factor) prepareGeometryChange(); QPolygonF scaledPolygon(m_polygon); - scaledPolygon.translate(-pivot); + + scaledPolygon.translate(pos() - pivot); QTransform trans; trans = trans.scale(factor.x(), factor.y()); m_polygon = trans.map(scaledPolygon); - m_polygon.translate(pivot); + m_polygon.translate(pivot - pos()); } void WorldItemZone::turnOn(const qreal angle) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h index cdc9691b4..af30c3470 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h @@ -129,7 +129,6 @@ public: enum { Type = QGraphicsItem::UserType + 1 }; - virtual void moveOn(const QPointF &offset) = 0; virtual void rotateOn(const QPointF &pivot, const qreal deltaAngle) = 0; // TODO: add modes: IgnoreAspectRatio, KeepAspectRatio virtual void scaleOn(const QPointF &pivot, const QPointF &factor) = 0; @@ -150,10 +149,10 @@ public: class WorldItemPoint: public AbstractWorldItem { public: - WorldItemPoint(const QPointF &point, const qreal angle, QGraphicsItem *parent = 0); + WorldItemPoint(const QPointF &point, const qreal angle, const qreal radius, + bool showArrow, QGraphicsItem *parent = 0); virtual ~WorldItemPoint(); - virtual void moveOn(const QPointF &offset); virtual void rotateOn(const QPointF &pivot, const qreal deltaAngle); virtual void scaleOn(const QPointF &pivot, const QPointF &factor); virtual void turnOn(const qreal angle); @@ -171,13 +170,16 @@ protected: private: // TODO - static const int SIZE_POINT = 4; + static const int SIZE_POINT = 3; QPen m_pen, m_selectedPen; QBrush m_brush, m_selectedBrush; + QPolygonF m_circle; + QVector m_arrow; QRectF m_rect; - qreal m_angle; + qreal m_angle, m_radius; + bool m_showArrow; }; /* @@ -191,7 +193,6 @@ public: WorldItemPath(const QPolygonF &polygon, QGraphicsItem *parent = 0); virtual ~WorldItemPath(); - virtual void moveOn(const QPointF &offset); virtual void rotateOn(const QPointF &pivot, const qreal deltaAngle); virtual void scaleOn(const QPointF &pivot, const QPointF &factor); virtual void turnOn(const qreal angle); @@ -221,7 +222,6 @@ public: WorldItemZone(const QPolygonF &polygon, QGraphicsItem *parent = 0); virtual ~WorldItemZone(); - virtual void moveOn(const QPointF &offset); virtual void rotateOn(const QPointF &pivot, const qreal deltaAngle); virtual void scaleOn(const QPointF &pivot, const QPointF &factor); virtual void turnOn(const qreal angle); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp index fb0f1463d..1e8a65506 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp @@ -38,6 +38,7 @@ #include #include #include +#include namespace WorldEditor { @@ -45,7 +46,8 @@ namespace WorldEditor WorldEditorWindow::WorldEditorWindow(QWidget *parent) : QMainWindow(parent), m_primitivesModel(0), - m_undoStack(0) + m_undoStack(0), + m_oglWidget(0) { m_ui.setupUi(this); m_undoStack = new QUndoStack(this); @@ -123,6 +125,25 @@ QUndoStack *WorldEditorWindow::undoStack() const return m_undoStack; } +void WorldEditorWindow::maybeSave() +{ + QMessageBox *messageBox = new QMessageBox(tr("SDI"), + tr("The data has been modified.\n" + "Do you want to save your changes?"), + QMessageBox::Warning, + QMessageBox::Yes | QMessageBox::Default, + QMessageBox::No, + QMessageBox::Cancel | QMessageBox::Escape, + this, Qt::Sheet); + + messageBox->setButtonText(QMessageBox::Yes, + tr("Save")); + + messageBox->setButtonText(QMessageBox::No, tr("Don’t Save")); + + messageBox->show(); +} + void WorldEditorWindow::open() { QString fileName = QFileDialog::getOpenFileName(this, diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h index 65d39ac58..58cd3a532 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h @@ -46,6 +46,7 @@ public: ~WorldEditorWindow(); QUndoStack *undoStack() const; + void maybeSave(); Q_SIGNALS: public Q_SLOTS: From 9c303dbf2f7ec080409ae609804f389b1f454b25 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Sat, 13 Aug 2011 13:07:06 +0300 Subject: [PATCH 55/89] Changed: #1302 When selecting primitives in the primitives dialog will be selected the appropriate graphics items in scene. --HG-- branch : gsoc2011-worldeditorqt --- .../src/plugins/world_editor/primitive_item.h | 2 + .../plugins/world_editor/primitives_view.cpp | 3 +- .../plugins/world_editor/primitives_view.h | 7 ++ .../world_editor/world_editor_actions.cpp | 52 +++++++++----- .../world_editor/world_editor_actions.h | 12 +++- .../world_editor/world_editor_scene.cpp | 68 ++++++++++++++----- .../plugins/world_editor/world_editor_scene.h | 7 +- .../world_editor/world_editor_scene_item.cpp | 50 +++++++++----- .../world_editor/world_editor_scene_item.h | 6 +- .../world_editor/world_editor_window.cpp | 44 ++++++++++++ .../world_editor/world_editor_window.h | 2 + 11 files changed, 193 insertions(+), 60 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h index 4940a622b..204068db0 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h @@ -173,6 +173,8 @@ private: NLLIGO::CPrimitives *m_primitives; }; +typedef QList NodeList; + } /* namespace WorldEditor */ Q_DECLARE_METATYPE(WorldEditor::Node *) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.cpp index f324da9b9..896218a54 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.cpp @@ -16,7 +16,6 @@ // Project includes #include "primitives_view.h" -#include "primitive_item.h" #include "primitives_model.h" #include "world_editor_actions.h" @@ -208,7 +207,7 @@ void PrimitivesView::addNewPrimitiveByClass(int value) QString className = node->primitiveClass()->DynamicChildren[value].ClassName.c_str(); m_undoStack->push(new AddPrimitiveByClassCommand(className, m_primitivesTreeModel->pathFromIndex(indexList.first()), - m_primitivesTreeModel)); + m_worldEditorScene, m_primitivesTreeModel)); } void PrimitivesView::generatePrimitives(int value) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.h index 18785b909..df317a93b 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.h @@ -18,6 +18,9 @@ #ifndef PRIMITIVES_VIEW_H #define PRIMITIVES_VIEW_H +// Project includes +#include "primitive_item.h" + // NeL includes #include @@ -28,6 +31,7 @@ #include #include #include +#include namespace LandscapeEditor { @@ -57,6 +61,9 @@ public: void setWorldScene(WorldEditorScene *worldEditorScene); virtual void setModel(PrimitivesTreeModel *model); +public Q_SLOTS: + //void selectPrimitives(); + private Q_SLOTS: void loadLandscape(); void loadRootPrimitive(); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp index 41de05f85..db4abcaa8 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp @@ -43,6 +43,29 @@ namespace WorldEditor { +QGraphicsItem *getGraphicsItem(Node *node) +{ + QGraphicsItem *result = 0; + if (node->type() == Node::PrimitiveNodeType) + { + PrimitiveNode *primitiveNode = static_cast(node); + if (primitiveNode != 0) + { + switch (primitiveNode->primitiveClass()->Type) + { + case NLLIGO::CPrimitiveClass::Point: + case NLLIGO::CPrimitiveClass::Path: + case NLLIGO::CPrimitiveClass::Zone: + { + result = qvariant_cast(primitiveNode->data(Constants::GRAPHICS_DATA_QT4_2D)); + break; + } + } + } + } + return result; +} + void addNewGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *model, WorldEditorScene *scene) { PrimitiveNode *node = static_cast(primIndex.internalPointer()); @@ -53,6 +76,10 @@ void addNewGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *mode NLLIGO::IPrimitive *primitive = node->primitive(); NLLIGO::CPrimVector *vec = 0; AbstractWorldItem *item = 0; + + // Draw arrow ? + bool showArrow = node->primitiveClass()->ShowArrow; + switch (node->primitiveClass()->Type) { case NLLIGO::CPrimitiveClass::Point: @@ -60,9 +87,6 @@ void addNewGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *mode vec = primitive->getPrimVector(); NLLIGO::CPrimPoint *primPoint = static_cast(primitive); - // Draw arrow ? - bool showArrow = node->primitiveClass()->ShowArrow; - // Have a radius ? std::string strRadius; qreal radius = 0; @@ -85,7 +109,7 @@ void addNewGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *mode ++vec; } - item = scene->addWorldItemPath(polygon); + item = scene->addWorldItemPath(polygon, showArrow); break; } case NLLIGO::CPrimitiveClass::Zone: @@ -153,22 +177,13 @@ void addNewGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *mode void removeGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *model, WorldEditorScene *scene) { - PrimitiveNode *node = static_cast(primIndex.internalPointer()); + Node *node = static_cast(primIndex.internalPointer()); if (node != 0) { - switch (node->primitiveClass()->Type) - { - case NLLIGO::CPrimitiveClass::Point: - case NLLIGO::CPrimitiveClass::Path: - case NLLIGO::CPrimitiveClass::Zone: - { - QGraphicsItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); - if (item != 0) - scene->removeWorldItem(item); - break; - } - } + QGraphicsItem *item = getGraphicsItem(node); + if (item != 0) + scene->removeWorldItem(item); } int count = model->rowCount(primIndex); @@ -334,10 +349,11 @@ void LoadRootPrimitiveCommand::redo() } AddPrimitiveByClassCommand::AddPrimitiveByClassCommand(const QString &className, const Path &parentIndex, - PrimitivesTreeModel *model, QUndoCommand *parent) + WorldEditorScene *scene, PrimitivesTreeModel *model, QUndoCommand *parent) : QUndoCommand(parent), m_className(className), m_parentIndex(parentIndex), + m_scene(scene), m_model(model) { setText(QString("Add %1").arg(m_className)); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h index 2eda788b4..a76e49466 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h @@ -36,7 +36,15 @@ namespace WorldEditor { class WorldEditorScene; +// Auxiliary operations + +// Return QGraphicsItem if node contains it +QGraphicsItem *getGraphicsItem(Node *node); + +// Scan primitives model for create/add necessary QGraphicsItems void addNewGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *model, WorldEditorScene *scene); + +// Recursive scan primitives model for delete Graphics Items void removeGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *model, WorldEditorScene *scene); QList graphicsItemsToPaths(const QList &items, PrimitivesTreeModel *model); //QList pathsToGraphicsItems(const QList &items, PrimitivesTreeModel *model); @@ -130,7 +138,8 @@ class AddPrimitiveByClassCommand: public QUndoCommand { public: AddPrimitiveByClassCommand(const QString &className, const Path &parentIndex, - PrimitivesTreeModel *model, QUndoCommand *parent = 0); + WorldEditorScene *scene, PrimitivesTreeModel *model, + QUndoCommand *parent = 0); virtual ~AddPrimitiveByClassCommand(); virtual void undo(); @@ -139,6 +148,7 @@ private: const QString m_className; Path m_parentIndex, m_newPrimIndex; + WorldEditorScene *m_scene; PrimitivesTreeModel *m_model; }; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp index b986d7c0c..7ec656f85 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp @@ -42,6 +42,9 @@ WorldEditorScene::WorldEditorScene(int sizeCell, PrimitivesTreeModel *model, QUn { setItemIndexMethod(NoIndex); + // TODO: get params from settings + setSceneRect(QRectF(-20 * 160, -20 * 160, 256 * 160, 256 * 160)); + m_pen1.setColor(QColor(50, 255, 155)); m_pen1.setWidth(0); @@ -67,7 +70,7 @@ AbstractWorldItem *WorldEditorScene::addWorldItemPoint(const QPointF &point, con return item; } -AbstractWorldItem *WorldEditorScene::addWorldItemPath(const QPolygonF &polyline) +AbstractWorldItem *WorldEditorScene::addWorldItemPath(const QPolygonF &polyline, bool showArrow) { WorldItemPath *item = new WorldItemPath(polyline); addItem(item); @@ -113,6 +116,31 @@ void WorldEditorScene::setEnabledEditPoint(bool enabled) m_editMode = enabled; } +void WorldEditorScene::updateSelection(const QList &selected, const QList &deselected) +{ + // Deselect and remove from list graphics items. + Q_FOREACH(QGraphicsItem *item, deselected) + { + // Item is selected? + int i = m_selectedItems.indexOf(item); + if (i != -1) + { + updateSelectedItem(item, false); + m_selectedItems.takeAt(i); + } + } + + // Select and add from list graphics items. + Q_FOREACH(QGraphicsItem *item, selected) + { + updateSelectedItem(item, true); + m_selectedItems.push_back(item); + } + + update(); + m_editedSelectedItems = true; +} + void WorldEditorScene::drawForeground(QPainter *painter, const QRectF &rect) { QGraphicsScene::drawForeground(painter, rect); @@ -138,15 +166,11 @@ void WorldEditorScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) { LandscapeEditor::LandscapeSceneBase::mousePressEvent(mouseEvent); - qreal x = mouseEvent->scenePos().x(); - qreal y = mouseEvent->scenePos().y(); - if (mouseEvent->button() != Qt::LeftButton) return; m_firstPick = mouseEvent->scenePos(); -// if ((!m_editedSelectedItems) && (m_mode != WorldEditorScene::SelectMode)) if ((!m_editedSelectedItems && m_selectedItems.isEmpty()) || (!calcBoundingRect(m_selectedItems).contains(mouseEvent->scenePos()))) { @@ -183,12 +207,19 @@ void WorldEditorScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) break; }; + m_selectHack = true; // if (m_selectedItems.isEmpty()) // m_selectionArea.setTopLeft(mouseEvent->scenePos()); } void WorldEditorScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) { + if (m_selectHack) + { + m_selectHack = false; + updateSelectedItems(true); + } + if (QApplication::mouseButtons() == Qt::LeftButton) { @@ -379,18 +410,23 @@ void WorldEditorScene::updateSelectedItems(bool value) { Q_FOREACH(QGraphicsItem *item, m_selectedItems) { - if (value) - { - item->setFlag(QGraphicsItem::ItemIsSelectable); - //item->setZValue(SELECTED_LAYER); - } - else - { - item->setFlag(QGraphicsItem::ItemIsSelectable, false); - //item->setZValue(UNSELECTED_LAYER); - } - item->setSelected(value); + updateSelectedItem(item, value); + } +} + +void WorldEditorScene::updateSelectedItem(QGraphicsItem *item, bool value) +{ + if (value) + { + item->setFlag(QGraphicsItem::ItemIsSelectable); + //item->setZValue(SELECTED_LAYER); + } + else + { + item->setFlag(QGraphicsItem::ItemIsSelectable, false); + //item->setZValue(UNSELECTED_LAYER); } + item->setSelected(value); } void WorldEditorScene::updatePickSelection(const QPointF &point) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h index c7868b15a..3ca055786 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h @@ -58,9 +58,8 @@ public: AbstractWorldItem *addWorldItemPoint(const QPointF &point, const qreal angle, const qreal radius, bool showArrow); - AbstractWorldItem *addWorldItemPath(const QPolygonF &polyline); + AbstractWorldItem *addWorldItemPath(const QPolygonF &polyline, bool showArrow); AbstractWorldItem *addWorldItemZone(const QPolygonF &polygon); - void removeWorldItem(QGraphicsItem *item); void setModeEdit(WorldEditorScene::ModeEdit mode); @@ -70,6 +69,7 @@ public: public Q_SLOTS: void setEnabledEditPoint(bool enabled); + void updateSelection(const QList &selected, const QList &deselected); protected: virtual void drawForeground(QPainter *painter, const QRectF &rect); @@ -83,12 +83,13 @@ private: QRectF calcBoundingRect(const QList &listItems); QPainterPath calcBoundingShape(const QList &listItems); void updateSelectedItems(bool value); - + void updateSelectedItem(QGraphicsItem *item, bool value); void updatePickSelection(const QPointF &point); QPen m_pen1, m_pen2; QBrush m_brush1, m_brush2; + bool m_selectHack; QPointF m_firstPick, m_scaleFactor, m_pivot; QRectF m_selectionArea; qreal m_firstPickX, m_firstPickY, m_angle; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.cpp index 0e65e6455..89ddd80a5 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.cpp @@ -349,21 +349,7 @@ WorldItemPoint::WorldItemPoint(const QPointF &point, const qreal angle, const qr m_selectedBrush.setColor(Qt::white); m_selectedBrush.setStyle(Qt::SolidPattern); - - if (m_radius != 0) - { - // Create circle - int segmentCount = 30; - QPointF circlePoint(m_radius, 0); - m_circle << circlePoint; - for (int i = 1; i < segmentCount + 1; ++i) - { - qreal angle = i * (2 * NLMISC::Pi / segmentCount); - circlePoint.setX(cos(angle) * m_radius); - circlePoint.setY(sin(angle) * m_radius); - m_circle << circlePoint; - } - } + createCircle(); // Create arrow if (showArrow) @@ -373,6 +359,7 @@ WorldItemPoint::WorldItemPoint(const QPointF &point, const qreal angle, const qr m_arrow.push_back(QLine(SIZE_ARROW - 2, 2, SIZE_ARROW, 0)); } + updateBoundingRect(); //setFlag(ItemIsSelectable); } @@ -424,6 +411,8 @@ void WorldItemPoint::turnOn(const qreal angle) void WorldItemPoint::radiusOn(const qreal radius) { + if (m_radius == 0) + return; } void WorldItemPoint::setColor(const QColor &color) @@ -432,18 +421,43 @@ void WorldItemPoint::setColor(const QColor &color) m_brush.setColor(color); } +void WorldItemPoint::createCircle() +{ + if (m_radius != 0) + { + // Create circle + int segmentCount = 30; + QPointF circlePoint(m_radius, 0); + m_circle << circlePoint; + for (int i = 1; i < segmentCount + 1; ++i) + { + qreal angle = i * (2 * NLMISC::Pi / segmentCount); + circlePoint.setX(cos(angle) * m_radius); + circlePoint.setY(sin(angle) * m_radius); + m_circle << circlePoint; + } + } +} + +void WorldItemPoint::updateBoundingRect() +{ + m_boundingRect.setCoords(-SIZE_POINT, -SIZE_POINT, SIZE_POINT, SIZE_POINT); + QRectF circleBoundingRect; + circleBoundingRect.setCoords(-m_radius, -m_radius, m_radius, m_radius); + m_boundingRect = m_boundingRect.united(circleBoundingRect); +} + QPainterPath WorldItemPoint::shape() const { QPainterPath path; - path.addRect(m_rect); - + path.addRect(m_boundingRect); return qt_graphicsItem_shapeFromPath(path, m_pen); } QRectF WorldItemPoint::boundingRect() const { - return m_rect; + return m_boundingRect; } void WorldItemPoint::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h index af30c3470..0625084bd 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h @@ -168,6 +168,8 @@ protected: virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value); private: + void createCircle(); + void updateBoundingRect(); // TODO static const int SIZE_POINT = 3; @@ -177,7 +179,7 @@ private: QPolygonF m_circle; QVector m_arrow; - QRectF m_rect; + QRectF m_rect, m_boundingRect; qreal m_angle, m_radius; bool m_showArrow; }; @@ -236,7 +238,7 @@ public: protected: virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value); - static const int TRANSPARENCY = 28; + static const int TRANSPARENCY = 38; QPen m_pen, m_selectedPen; QBrush m_brush, m_selectedBrush; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp index 1e8a65506..e00e804f3 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp @@ -105,6 +105,9 @@ WorldEditorWindow::WorldEditorWindow(QWidget *parent) connect(m_ui.saveWorldEditAction, SIGNAL(triggered()), this, SLOT(saveWorldEditFile())); connect(m_ui.visibleGridAction, SIGNAL(toggled(bool)), m_ui.graphicsView, SLOT(setVisibleGrid(bool))); + connect(m_ui.treePrimitivesView->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), + this, SLOT(updateSelection(QItemSelection, QItemSelection))); + m_statusBarTimer = new QTimer(this); connect(m_statusBarTimer, SIGNAL(timeout()), this, SLOT(updateStatusBar())); @@ -250,6 +253,47 @@ void WorldEditorWindow::updateStatusBar() m_statusInfo->setText(m_worldEditorScene->zoneNameFromMousePos()); } +void WorldEditorWindow::updateSelection(const QItemSelection &selected, const QItemSelection &deselected) +{ + m_ui.pointsAction->setChecked(false); + + NodeList nodesSelected; + Q_FOREACH(QModelIndex modelIndex, selected.indexes()) + { + Node *node = static_cast(modelIndex.internalPointer()); + nodesSelected.push_back(node); + } + + NodeList nodesDeselected; + Q_FOREACH(QModelIndex modelIndex, deselected.indexes()) + { + Node *node = static_cast(modelIndex.internalPointer()); + nodesDeselected.push_back(node); + } + + // TODO: update property editor + // ... + + QList itemSelected; + Q_FOREACH(Node *node, nodesSelected) + { + QGraphicsItem *item = getGraphicsItem(node); + if (item != 0) + itemSelected.push_back(item); + } + + QList itemDeselected; + Q_FOREACH(Node *node, nodesDeselected) + { + QGraphicsItem *item = getGraphicsItem(node); + if (item != 0) + itemDeselected.push_back(item); + } + + // Update world editor scene + m_worldEditorScene->updateSelection(itemSelected, itemDeselected); +} + void WorldEditorWindow::showEvent(QShowEvent *showEvent) { QMainWindow::showEvent(showEvent); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h index 58cd3a532..5844489f6 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h @@ -60,6 +60,8 @@ private Q_SLOTS: void setMode(int value); void updateStatusBar(); + void updateSelection(const QItemSelection &selected, const QItemSelection &deselected); + protected: virtual void showEvent(QShowEvent *showEvent); virtual void hideEvent(QHideEvent *hideEvent); From 3ede2b845bddaeada0cb15508ebe8f548e0b844e Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Mon, 15 Aug 2011 17:03:28 +0300 Subject: [PATCH 56/89] Changed: #1302 Added edit points mode with undo/redo commands and turn undo/redo command for PointWorldItem. --HG-- branch : gsoc2011-worldeditorqt --- .../src/plugins/world_editor/primitive_item.h | 1 + .../plugins/world_editor/primitives_view.h | 3 - .../world_editor/world_editor_actions.cpp | 108 ++- .../world_editor/world_editor_actions.h | 43 +- .../world_editor/world_editor_scene.cpp | 426 +++++++--- .../plugins/world_editor/world_editor_scene.h | 23 +- .../world_editor/world_editor_scene_item.cpp | 790 +++++++++++------- .../world_editor/world_editor_scene_item.h | 208 +++-- .../world_editor/world_editor_window.cpp | 3 +- .../world_editor/world_editor_window.ui | 19 +- 10 files changed, 1091 insertions(+), 533 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h index 204068db0..1b2a89d4c 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h @@ -177,6 +177,7 @@ typedef QList NodeList; } /* namespace WorldEditor */ +// Enable the use of QVariant with this class. Q_DECLARE_METATYPE(WorldEditor::Node *) #endif // PRIMITIVE_ITEM_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.h index df317a93b..eae9187ac 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.h @@ -61,9 +61,6 @@ public: void setWorldScene(WorldEditorScene *worldEditorScene); virtual void setModel(PrimitivesTreeModel *model); -public Q_SLOTS: - //void selectPrimitives(); - private Q_SLOTS: void loadLandscape(); void loadRootPrimitive(); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp index db4abcaa8..45adf49ce 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp @@ -204,12 +204,16 @@ QList graphicsItemsToPaths(const QList &items, Primitives return result; } -/* -QList pathsToGraphicsItems(const QList &items, PrimitivesTreeModel *model) +QList polygonsFromItems(const QList &items) { - QList result; + QList result; + Q_FOREACH(QGraphicsItem *item, items) + { + AbstractWorldItem *worldItem = qgraphicsitem_cast(item); + result.push_back(worldItem->polygon()); + } + return result; } -*/ CreateWorldCommand::CreateWorldCommand(const QString &fileName, PrimitivesTreeModel *model, QUndoCommand *parent) : QUndoCommand(parent), @@ -310,6 +314,8 @@ LoadRootPrimitiveCommand::~LoadRootPrimitiveCommand() void LoadRootPrimitiveCommand::undo() { + m_scene->setEnabledEditPoints(false); + QModelIndex index = m_model->pathToIndex(m_rootPrimIndex); removeGraphicsItems(index, m_model, m_scene); @@ -323,6 +329,8 @@ void LoadRootPrimitiveCommand::undo() void LoadRootPrimitiveCommand::redo() { + m_scene->setEnabledEditPoints(false); + NLLIGO::CPrimitives *primitives = new NLLIGO::CPrimitives(); // set the primitive context @@ -365,6 +373,8 @@ AddPrimitiveByClassCommand::~AddPrimitiveByClassCommand() void AddPrimitiveByClassCommand::undo() { + m_scene->setEnabledEditPoints(false); + QModelIndex index = m_model->pathToIndex(m_newPrimIndex); PrimitiveNode *node = static_cast(index.internalPointer()); @@ -381,6 +391,8 @@ void AddPrimitiveByClassCommand::undo() void AddPrimitiveByClassCommand::redo() { + m_scene->setEnabledEditPoints(false); + QModelIndex parentIndex = m_model->pathToIndex(m_parentIndex); PrimitiveNode *parentNode = static_cast(parentIndex.internalPointer()); const NLLIGO::CPrimitiveClass *primClass = parentNode->primitiveClass(); @@ -404,11 +416,12 @@ void AddPrimitiveByClassCommand::redo() } MoveWorldItemsCommand::MoveWorldItemsCommand(const QList &items, const QPointF &offset, - PrimitivesTreeModel *model, QUndoCommand *parent) + WorldEditorScene *scene, PrimitivesTreeModel *model, QUndoCommand *parent) : QUndoCommand(parent), m_listPaths(graphicsItemsToPaths(items, model)), m_offset(offset), m_model(model), + m_scene(scene), m_firstRun(true) { setText("Move item(s)"); @@ -420,35 +433,42 @@ MoveWorldItemsCommand::~MoveWorldItemsCommand() void MoveWorldItemsCommand::undo() { + bool pointsMode = m_scene->isEnabledEditPoints(); + m_scene->setEnabledEditPoints(false); for (int i = 0; i < m_listPaths.count(); ++i) { Node *node = m_model->pathToNode(m_listPaths.at(i)); AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); item->moveBy(-m_offset.x(), -m_offset.y()); } + m_scene->setEnabledEditPoints(pointsMode); } void MoveWorldItemsCommand::redo() { if (!m_firstRun) { + bool pointsMode = m_scene->isEnabledEditPoints(); + m_scene->setEnabledEditPoints(false); for (int i = 0; i < m_listPaths.count(); ++i) { Node *node = m_model->pathToNode(m_listPaths.at(i)); AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); item->moveBy(m_offset.x(), m_offset.y()); } + m_scene->setEnabledEditPoints(pointsMode); } m_firstRun = false; } RotateWorldItemsCommand::RotateWorldItemsCommand(const QList &items, const qreal angle, - const QPointF &pivot, PrimitivesTreeModel *model, QUndoCommand *parent) + const QPointF &pivot, WorldEditorScene *scene, PrimitivesTreeModel *model, QUndoCommand *parent) : QUndoCommand(parent), m_listPaths(graphicsItemsToPaths(items, model)), m_angle(angle), m_pivot(pivot), m_model(model), + m_scene(scene), m_firstRun(true) { setText(QString("Rotate item(s) %1").arg(m_angle)); @@ -460,35 +480,42 @@ RotateWorldItemsCommand::~RotateWorldItemsCommand() void RotateWorldItemsCommand::undo() { + bool pointsMode = m_scene->isEnabledEditPoints(); + m_scene->setEnabledEditPoints(false); for (int i = 0; i < m_listPaths.count(); ++i) { Node *node = m_model->pathToNode(m_listPaths.at(i)); AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); item->rotateOn(m_pivot, -m_angle); } + m_scene->setEnabledEditPoints(pointsMode); } void RotateWorldItemsCommand::redo() { if (!m_firstRun) { + bool pointsMode = m_scene->isEnabledEditPoints(); + m_scene->setEnabledEditPoints(false); for (int i = 0; i < m_listPaths.count(); ++i) { Node *node = m_model->pathToNode(m_listPaths.at(i)); AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); item->rotateOn(m_pivot, m_angle); } + m_scene->setEnabledEditPoints(pointsMode); } m_firstRun = false; } ScaleWorldItemsCommand::ScaleWorldItemsCommand(const QList &items, const QPointF &factor, - const QPointF &pivot, PrimitivesTreeModel *model, QUndoCommand *parent) + const QPointF &pivot, WorldEditorScene *scene, PrimitivesTreeModel *model, QUndoCommand *parent) : QUndoCommand(parent), m_listPaths(graphicsItemsToPaths(items, model)), m_factor(factor), m_pivot(pivot), m_model(model), + m_scene(scene), m_firstRun(true) { setText("Scale item(s)"); @@ -500,6 +527,8 @@ ScaleWorldItemsCommand::~ScaleWorldItemsCommand() void ScaleWorldItemsCommand::undo() { + bool pointsMode = m_scene->isEnabledEditPoints(); + m_scene->setEnabledEditPoints(false); QPointF m_invertFactor(1 / m_factor.x(), 1 / m_factor.y()); for (int i = 0; i < m_listPaths.count(); ++i) { @@ -507,28 +536,33 @@ void ScaleWorldItemsCommand::undo() AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); item->scaleOn(m_pivot, m_invertFactor); } + m_scene->setEnabledEditPoints(pointsMode); } void ScaleWorldItemsCommand::redo() { if (!m_firstRun) { + bool pointsMode = m_scene->isEnabledEditPoints(); + m_scene->setEnabledEditPoints(false); for (int i = 0; i < m_listPaths.count(); ++i) { Node *node = m_model->pathToNode(m_listPaths.at(i)); AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); item->scaleOn(m_pivot, m_factor); } + m_scene->setEnabledEditPoints(pointsMode); } m_firstRun = false; } TurnWorldItemsCommand::TurnWorldItemsCommand(const QList &items, const qreal angle, - PrimitivesTreeModel *model, QUndoCommand *parent) + WorldEditorScene *scene, PrimitivesTreeModel *model, QUndoCommand *parent) : QUndoCommand(parent), m_listPaths(graphicsItemsToPaths(items, model)), m_angle(angle), m_model(model), + m_scene(scene), m_firstRun(true) { setText(QString("Turn item(s) %1").arg(m_angle)); @@ -540,24 +574,82 @@ TurnWorldItemsCommand::~TurnWorldItemsCommand() void TurnWorldItemsCommand::undo() { + bool pointsMode = m_scene->isEnabledEditPoints(); + m_scene->setEnabledEditPoints(false); for (int i = 0; i < m_listPaths.count(); ++i) { Node *node = m_model->pathToNode(m_listPaths.at(i)); AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); item->turnOn(-m_angle); } + m_scene->setEnabledEditPoints(pointsMode); } void TurnWorldItemsCommand::redo() { if (!m_firstRun) { + bool pointsMode = m_scene->isEnabledEditPoints(); + m_scene->setEnabledEditPoints(false); for (int i = 0; i < m_listPaths.count(); ++i) { Node *node = m_model->pathToNode(m_listPaths.at(i)); AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); item->turnOn(m_angle); } + m_scene->setEnabledEditPoints(pointsMode); + } + + m_firstRun = false; +} + +ShapeWorldItemsCommand::ShapeWorldItemsCommand(const QList &items, const QList &polygons, + WorldEditorScene *scene, PrimitivesTreeModel *model, + QUndoCommand *parent) + : QUndoCommand(parent), + m_listPaths(graphicsItemsToPaths(items, model)), + m_redoPolygons(polygons), + m_undoPolygons(polygonsFromItems(items)), + m_model(model), + m_scene(scene), + m_firstRun(true) +{ + setText("Change shape"); +} + +ShapeWorldItemsCommand::~ShapeWorldItemsCommand() +{ +} + +void ShapeWorldItemsCommand::undo() +{ + bool pointsMode = m_scene->isEnabledEditPoints(); + m_scene->setEnabledEditPoints(false); + + for (int i = 0; i < m_listPaths.count(); ++i) + { + Node *node = m_model->pathToNode(m_listPaths.at(i)); + AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); + item->setPolygon(m_redoPolygons.at(i)); + } + + m_scene->setEnabledEditPoints(pointsMode); +} + +void ShapeWorldItemsCommand::redo() +{ + if (!m_firstRun) + { + bool pointsMode = m_scene->isEnabledEditPoints(); + m_scene->setEnabledEditPoints(false); + + for (int i = 0; i < m_listPaths.count(); ++i) + { + Node *node = m_model->pathToNode(m_listPaths.at(i)); + AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); + item->setPolygon(m_undoPolygons.at(i)); + } + m_scene->setEnabledEditPoints(pointsMode); } m_firstRun = false; } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h index a76e49466..fcb510605 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h @@ -47,7 +47,8 @@ void addNewGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *mode // Recursive scan primitives model for delete Graphics Items void removeGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *model, WorldEditorScene *scene); QList graphicsItemsToPaths(const QList &items, PrimitivesTreeModel *model); -//QList pathsToGraphicsItems(const QList &items, PrimitivesTreeModel *model); + +QList polygonsFromItems(const QList &items); /** @class CreateWorldCommand @@ -161,7 +162,8 @@ class MoveWorldItemsCommand: public QUndoCommand { public: MoveWorldItemsCommand(const QList &items, const QPointF &offset, - PrimitivesTreeModel *model, QUndoCommand *parent = 0); + WorldEditorScene *scene, PrimitivesTreeModel *model, + QUndoCommand *parent = 0); virtual ~MoveWorldItemsCommand(); virtual void undo(); @@ -171,6 +173,7 @@ private: const QList m_listPaths; const QPointF m_offset; PrimitivesTreeModel *const m_model; + WorldEditorScene *m_scene; bool m_firstRun; }; @@ -183,7 +186,8 @@ class RotateWorldItemsCommand: public QUndoCommand { public: RotateWorldItemsCommand(const QList &items, const qreal angle, - const QPointF &pivot, PrimitivesTreeModel *model, QUndoCommand *parent = 0); + const QPointF &pivot, WorldEditorScene *scene, + PrimitivesTreeModel *model, QUndoCommand *parent = 0); virtual ~RotateWorldItemsCommand(); virtual void undo(); @@ -194,6 +198,7 @@ private: const qreal m_angle; const QPointF m_pivot; PrimitivesTreeModel *const m_model; + WorldEditorScene *m_scene; bool m_firstRun; }; @@ -206,7 +211,8 @@ class ScaleWorldItemsCommand: public QUndoCommand { public: ScaleWorldItemsCommand(const QList &items, const QPointF &factor, - const QPointF &pivot, PrimitivesTreeModel *model, QUndoCommand *parent = 0); + const QPointF &pivot, WorldEditorScene *scene, + PrimitivesTreeModel *model, QUndoCommand *parent = 0); virtual ~ScaleWorldItemsCommand(); virtual void undo(); @@ -217,6 +223,7 @@ private: const QPointF m_factor; const QPointF m_pivot; PrimitivesTreeModel *const m_model; + WorldEditorScene *m_scene; bool m_firstRun; }; @@ -229,7 +236,8 @@ class TurnWorldItemsCommand: public QUndoCommand { public: TurnWorldItemsCommand(const QList &items, const qreal angle, - PrimitivesTreeModel *model, QUndoCommand *parent = 0); + WorldEditorScene *scene, PrimitivesTreeModel *model, + QUndoCommand *parent = 0); virtual ~TurnWorldItemsCommand(); virtual void undo(); @@ -239,9 +247,34 @@ private: const QList m_listPaths; const qreal m_angle; PrimitivesTreeModel *const m_model; + WorldEditorScene *m_scene; bool m_firstRun; }; +/** +@class TurnWorldItemsCommand +@brief +@details +*/ +class ShapeWorldItemsCommand: public QUndoCommand +{ +public: + ShapeWorldItemsCommand(const QList &items, const QList &polygons, + WorldEditorScene *scene, PrimitivesTreeModel *model, + QUndoCommand *parent = 0); + virtual ~ShapeWorldItemsCommand(); + + virtual void undo(); + virtual void redo(); +private: + + const QList m_listPaths; + const QList m_redoPolygons; + const QList m_undoPolygons; + PrimitivesTreeModel *const m_model; + WorldEditorScene *m_scene; + bool m_firstRun; +}; } /* namespace WorldEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp index 7ec656f85..749392631 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp @@ -36,7 +36,7 @@ WorldEditorScene::WorldEditorScene(int sizeCell, PrimitivesTreeModel *model, QUn m_editedSelectedItems(false), m_lastPickedPrimitive(0), m_mode(SelectMode), - m_editMode(false), + m_pointsMode(false), m_undoStack(undoStack), m_model(model) { @@ -86,7 +86,7 @@ AbstractWorldItem *WorldEditorScene::addWorldItemZone(const QPolygonF &polygon) void WorldEditorScene::removeWorldItem(QGraphicsItem *item) { - updateSelectedItems(true); + updateSelectedWorldItems(true); m_selectedItems.clear(); m_editedSelectedItems = false; m_firstSelection = false; @@ -106,14 +106,26 @@ WorldEditorScene::ModeEdit WorldEditorScene::editMode() const return m_mode; } -bool WorldEditorScene::isEnabledEditPoint() const +bool WorldEditorScene::isEnabledEditPoints() const { - return m_editMode; + return m_pointsMode; } -void WorldEditorScene::setEnabledEditPoint(bool enabled) +void WorldEditorScene::setEnabledEditPoints(bool enabled) { - m_editMode = enabled; + if (m_pointsMode == enabled) + return; + + m_pointsMode = enabled; + + Q_FOREACH(QGraphicsItem *item, m_selectedItems) + { + AbstractWorldItem *worldItem = qgraphicsitem_cast(item); + if (worldItem != 0) + worldItem->setEnabledSubPoints(enabled); + } + + m_selectedPoints.clear(); } void WorldEditorScene::updateSelection(const QList &selected, const QList &deselected) @@ -125,7 +137,7 @@ void WorldEditorScene::updateSelection(const QList &selected, c int i = m_selectedItems.indexOf(item); if (i != -1) { - updateSelectedItem(item, false); + updateSelectedWorldItem(item, false); m_selectedItems.takeAt(i); } } @@ -133,12 +145,17 @@ void WorldEditorScene::updateSelection(const QList &selected, c // Select and add from list graphics items. Q_FOREACH(QGraphicsItem *item, selected) { - updateSelectedItem(item, true); - m_selectedItems.push_back(item); + // Item is selected? + int i = m_selectedItems.indexOf(item); + if (i == -1) + { + updateSelectedWorldItem(item, true); + m_selectedItems.push_back(item); + } } update(); - m_editedSelectedItems = true; + m_firstSelection = true; } void WorldEditorScene::drawForeground(QPainter *painter, const QRectF &rect) @@ -164,65 +181,68 @@ void WorldEditorScene::drawForeground(QPainter *painter, const QRectF &rect) void WorldEditorScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) { - LandscapeEditor::LandscapeSceneBase::mousePressEvent(mouseEvent); + m_firstPick = mouseEvent->scenePos(); - if (mouseEvent->button() != Qt::LeftButton) - return; + if (m_pointsMode) + { + m_polygons = polygonsFromItems(m_selectedItems); - m_firstPick = mouseEvent->scenePos(); + if (mouseEvent->button() == Qt::LeftButton) + { + // Create new sub-points + // Call method mousePressEvent for point located under mouse + LandscapeEditor::LandscapeSceneBase::mousePressEvent(mouseEvent); + + if ((!m_editedSelectedItems && m_selectedPoints.isEmpty()) || + (!calcBoundingRect(m_selectedPoints).contains(mouseEvent->scenePos()))) + { + updatePickSelectionPoints(mouseEvent->scenePos()); + m_firstSelection = true; + } + m_pivot = calcBoundingRect(m_selectedPoints).center(); + } + else if (mouseEvent->button() == Qt::RightButton) + { + updateSelectedPointItems(false); + m_selectedPoints.clear(); - if ((!m_editedSelectedItems && m_selectedItems.isEmpty()) || - (!calcBoundingRect(m_selectedItems).contains(mouseEvent->scenePos()))) + // Delete sub-points if it located under mouse + // Call method mousePressEvent for point located under mouse + LandscapeEditor::LandscapeSceneBase::mousePressEvent(mouseEvent); + } + } + else { - updatePickSelection(mouseEvent->scenePos()); - m_firstSelection = true; + LandscapeEditor::LandscapeSceneBase::mousePressEvent(mouseEvent); + + if (mouseEvent->button() != Qt::LeftButton) + return; + + if ((!m_editedSelectedItems && m_selectedItems.isEmpty()) || + (!calcBoundingRect(m_selectedItems).contains(mouseEvent->scenePos()))) + { + updatePickSelection(mouseEvent->scenePos()); + m_firstSelection = true; + } + + m_pivot = calcBoundingRect(m_selectedItems).center(); } m_editedSelectedItems = false; + m_angle = 0; + m_scaleFactor = QPointF(1.0, 1.0); - switch (m_mode) - { - case WorldEditorScene::SelectMode: - { + if (m_mode == WorldEditorScene::SelectMode) m_selectionArea.setTopLeft(mouseEvent->scenePos()); - break; - } - case WorldEditorScene::MoveMode: - { - break; - } - case WorldEditorScene::RotateMode: - m_angle = 0; - m_pivot = calcBoundingRect(m_selectedItems).center(); - break; - case WorldEditorScene::ScaleMode: - m_scaleFactor = QPointF(1.0, 1.0); - m_pivot = calcBoundingRect(m_selectedItems).center(); - break; - case WorldEditorScene::TurnMode: - m_angle = 0; - m_pivot = calcBoundingRect(m_selectedItems).center(); - break; - case WorldEditorScene::RadiusMode: - break; - }; - m_selectHack = true; // if (m_selectedItems.isEmpty()) // m_selectionArea.setTopLeft(mouseEvent->scenePos()); } void WorldEditorScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) { - if (m_selectHack) - { - m_selectHack = false; - updateSelectedItems(true); - } - if (QApplication::mouseButtons() == Qt::LeftButton) { - QPointF offset(mouseEvent->scenePos() - mouseEvent->lastScenePos()); m_selectionArea.setBottomRight(mouseEvent->scenePos()); @@ -233,9 +253,19 @@ void WorldEditorScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) break; case WorldEditorScene::MoveMode: { - Q_FOREACH(QGraphicsItem *item, m_selectedItems) + if (m_pointsMode) + { + Q_FOREACH(QGraphicsItem *item, m_selectedPoints) + { + item->moveBy(offset.x(), offset.y()); + } + } + else { - item->moveBy(offset.x(), offset.y()); + Q_FOREACH(QGraphicsItem *item, m_selectedItems) + { + item->moveBy(offset.x(), offset.y()); + } } break; } @@ -248,9 +278,19 @@ void WorldEditorScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) m_angle += angle; - Q_FOREACH(QGraphicsItem *item, m_selectedItems) + if (m_pointsMode) { - qgraphicsitem_cast(item)->rotateOn(m_pivot, angle); + Q_FOREACH(QGraphicsItem *item, m_selectedPoints) + { + qgraphicsitem_cast(item)->rotateOn(m_pivot, angle); + } + } + else + { + Q_FOREACH(QGraphicsItem *item, m_selectedItems) + { + qgraphicsitem_cast(item)->rotateOn(m_pivot, angle); + } } break; } @@ -270,9 +310,19 @@ void WorldEditorScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) m_scaleFactor.setX(offset.x() * m_scaleFactor.x()); m_scaleFactor.setY(offset.y() * m_scaleFactor.y()); - Q_FOREACH(QGraphicsItem *item, m_selectedItems) + if (m_pointsMode) { - qgraphicsitem_cast(item)->scaleOn(m_pivot, offset); + Q_FOREACH(QGraphicsItem *item, m_selectedPoints) + { + qgraphicsitem_cast(item)->scaleOn(m_pivot, offset); + } + } + else + { + Q_FOREACH(QGraphicsItem *item, m_selectedItems) + { + qgraphicsitem_cast(item)->scaleOn(m_pivot, offset); + } } break; } @@ -296,91 +346,133 @@ void WorldEditorScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) break; }; - if ((editMode() != WorldEditorScene::SelectMode) && (!m_selectedItems.isEmpty())) - m_editedSelectedItems = true; + if (m_pointsMode) + { + if ((editMode() != WorldEditorScene::SelectMode) && (!m_selectedPoints.isEmpty())) + m_editedSelectedItems = true; + else + m_editedSelectedItems = false; + } else - m_editedSelectedItems = false; + { + if ((editMode() != WorldEditorScene::SelectMode) && (!m_selectedItems.isEmpty())) + m_editedSelectedItems = true; + else + m_editedSelectedItems = false; + } update(); } - /*m_mouseX = mouseEvent->scenePos().x(); - m_mouseY = mouseEvent->scenePos().y() - m_cellSize; - */ + LandscapeEditor::LandscapeSceneBase::mouseMoveEvent(mouseEvent); } void WorldEditorScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent) { - if (mouseEvent->button() != Qt::LeftButton) - return; - - if (m_editedSelectedItems) + if (m_pointsMode) { - switch (m_mode) + if (mouseEvent->button() == Qt::LeftButton) { - case WorldEditorScene::SelectMode: - break; - - case WorldEditorScene::MoveMode: - { - QPointF offset = mouseEvent->scenePos() - m_firstPick; - m_undoStack->push(new MoveWorldItemsCommand(m_selectedItems, offset, m_model)); - break; + if ((m_selectionArea.left() != 0) && (m_selectionArea.right() != 0)) + { + QList listItems; + + // Clear selection + updateSelectedPointItems(false); + m_selectedPoints.clear(); + + if (m_selectionArea.left() < m_selectionArea.right()) + listItems = items(m_selectionArea, Qt::IntersectsItemShape, Qt::AscendingOrder); + else + listItems = items(m_selectionArea, Qt::ContainsItemShape, Qt::AscendingOrder); + + Q_FOREACH(QGraphicsItem *item, listItems) + { + if (qgraphicsitem_cast(item) == 0) + continue; + + m_selectedPoints.push_back(item); + } + updateSelectedPointItems(true); + m_selectionArea = QRectF(); + update(); + } + else + { + if ((!m_editedSelectedItems) && (!m_firstSelection)) + updatePickSelectionPoints(mouseEvent->scenePos()); + else + m_firstSelection = false; + } } - case WorldEditorScene::RotateMode: - m_undoStack->push(new RotateWorldItemsCommand(m_selectedItems, m_angle, m_pivot, m_model)); - break; - case WorldEditorScene::ScaleMode: - m_undoStack->push(new ScaleWorldItemsCommand(m_selectedItems, m_scaleFactor, m_pivot, m_model)); - break; - case WorldEditorScene::TurnMode: - m_undoStack->push(new TurnWorldItemsCommand(m_selectedItems, m_angle, m_model)); - break; - case WorldEditorScene::RadiusMode: - break; - }; + checkUndo(); } - - if ((m_selectionArea.left() != 0) && (m_selectionArea.right() != 0)) + else { - QList listItems; - - // Clear selection - updateSelectedItems(false); - m_selectedItems.clear(); + if (mouseEvent->button() != Qt::LeftButton) + return; - if (m_selectionArea.left() < m_selectionArea.right()) - { - listItems = items(m_selectionArea, Qt::IntersectsItemShape, - Qt::AscendingOrder); - } - else + if (m_editedSelectedItems) { - listItems = items(m_selectionArea, Qt::ContainsItemShape, - Qt::AscendingOrder); + switch (m_mode) + { + case WorldEditorScene::SelectMode: + break; + + case WorldEditorScene::MoveMode: + { + QPointF offset = mouseEvent->scenePos() - m_firstPick; + m_undoStack->push(new MoveWorldItemsCommand(m_selectedItems, offset, this, m_model)); + break; + } + case WorldEditorScene::RotateMode: + m_undoStack->push(new RotateWorldItemsCommand(m_selectedItems, m_angle, m_pivot, this, m_model)); + break; + case WorldEditorScene::ScaleMode: + m_undoStack->push(new ScaleWorldItemsCommand(m_selectedItems, m_scaleFactor, m_pivot, this, m_model)); + break; + case WorldEditorScene::TurnMode: + m_undoStack->push(new TurnWorldItemsCommand(m_selectedItems, m_angle, this, m_model)); + break; + case WorldEditorScene::RadiusMode: + break; + }; } - Q_FOREACH(QGraphicsItem *item, listItems) + if ((m_selectionArea.left() != 0) && (m_selectionArea.right() != 0)) { - if (qgraphicsitem_cast(item) == 0) - continue; + QList listItems; - m_selectedItems.push_back(item); + // Clear selection + updateSelectedWorldItems(false); + m_selectedItems.clear(); + + if (m_selectionArea.left() < m_selectionArea.right()) + listItems = items(m_selectionArea, Qt::IntersectsItemShape, Qt::AscendingOrder); + else + listItems = items(m_selectionArea, Qt::ContainsItemShape, Qt::AscendingOrder); + + Q_FOREACH(QGraphicsItem *item, listItems) + { + if (qgraphicsitem_cast(item) == 0) + continue; + + m_selectedItems.push_back(item); + } + updateSelectedWorldItems(true); + m_selectionArea = QRectF(); + update(); } - updateSelectedItems(true); - m_selectionArea = QRectF(); - update(); - } - else - { - if ((!m_editedSelectedItems) && (!m_firstSelection)) - updatePickSelection(mouseEvent->scenePos()); else - m_firstSelection = false; - - m_selectionArea = QRectF(); + { + if ((!m_editedSelectedItems) && (!m_firstSelection)) + updatePickSelection(mouseEvent->scenePos()); + else + m_firstSelection = false; + } } + m_selectionArea = QRectF(); LandscapeEditor::LandscapeSceneBase::mouseReleaseEvent(mouseEvent); } @@ -390,7 +482,7 @@ QRectF WorldEditorScene::calcBoundingRect(const QList &listItem Q_FOREACH(QGraphicsItem *item, listItems) { QRectF itemRect = item->boundingRect(); - rect = rect.united(itemRect.translated(item->pos())); + rect = rect.united(itemRect.translated(item->scenePos())); } return rect; } @@ -401,38 +493,46 @@ QPainterPath WorldEditorScene::calcBoundingShape(const QList &l Q_FOREACH(QGraphicsItem *item, listItems) { QPainterPath itemPath = item->shape(); - painterPath = painterPath.united(itemPath.translated(item->pos())); + painterPath = painterPath.united(itemPath.translated(item->scenePos())); } return painterPath; } -void WorldEditorScene::updateSelectedItems(bool value) +void WorldEditorScene::updateSelectedWorldItems(bool value) { Q_FOREACH(QGraphicsItem *item, m_selectedItems) { - updateSelectedItem(item, value); + updateSelectedWorldItem(item, value); } + update(); } -void WorldEditorScene::updateSelectedItem(QGraphicsItem *item, bool value) +void WorldEditorScene::updateSelectedWorldItem(QGraphicsItem *item, bool value) { - if (value) - { - item->setFlag(QGraphicsItem::ItemIsSelectable); - //item->setZValue(SELECTED_LAYER); - } - else + AbstractWorldItem *worldItem = qgraphicsitem_cast(item); + if (worldItem != 0) + worldItem->setActived(value); +} + +void WorldEditorScene::updateSelectedPointItems(bool value) +{ + Q_FOREACH(QGraphicsItem *item, m_selectedPoints) { - item->setFlag(QGraphicsItem::ItemIsSelectable, false); - //item->setZValue(UNSELECTED_LAYER); + updateSelectedPointItem(item, value); } - item->setSelected(value); + update(); +} + +void WorldEditorScene::updateSelectedPointItem(QGraphicsItem *item, bool value) +{ + WorldItemSubPoint *worldItem = qgraphicsitem_cast(item); + if (worldItem != 0) + worldItem->setActived(value); } void WorldEditorScene::updatePickSelection(const QPointF &point) { - //clearSelection(); - updateSelectedItems(false); + updateSelectedWorldItems(false); m_selectedItems.clear(); QList listItems = items(point, Qt::ContainsItemShape, @@ -454,7 +554,63 @@ void WorldEditorScene::updatePickSelection(const QPointF &point) m_lastPickedPrimitive %= worldItemsItems.size(); m_selectedItems.push_back(worldItemsItems.at(m_lastPickedPrimitive)); - updateSelectedItems(true); + updateSelectedWorldItems(true); + } +} + +void WorldEditorScene::updatePickSelectionPoints(const QPointF &point) +{ + updateSelectedPointItems(false); + m_selectedPoints.clear(); + + QList listItems = items(point, Qt::IntersectsItemBoundingRect, + Qt::AscendingOrder); + + QList subPointsItems; + + Q_FOREACH(QGraphicsItem *item, listItems) + { + WorldItemSubPoint *subPointItem = qgraphicsitem_cast(item); + if (subPointItem != 0) + { + if (subPointItem->subPointType() == WorldItemSubPoint::EdgeType) + subPointsItems.push_back(subPointItem); + } + } + + if (!subPointsItems.isEmpty()) + { + // Next primitives + m_lastPickedPrimitive++; + m_lastPickedPrimitive %= subPointsItems.size(); + + m_selectedPoints.push_back(subPointsItems.at(m_lastPickedPrimitive)); + updateSelectedPointItems(true); + } +} + +void WorldEditorScene::checkUndo() +{ + if (m_pointsMode) + { + QList items; + QList polygons; + Q_FOREACH(QGraphicsItem *item, m_selectedItems) + { + AbstractWorldItem *worldItem = qgraphicsitem_cast(item); + if (worldItem->isShapeChanged()) + { + items.push_back(item); + polygons.push_back(m_polygons.at(m_selectedItems.indexOf(item))); + worldItem->setShapeChanged(false); + } + } + + if (!items.isEmpty()) + { + m_undoStack->push(new ShapeWorldItemsCommand(items, polygons, this, m_model)); + m_polygons.clear(); + } } } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h index 3ca055786..adf491889 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h @@ -65,10 +65,13 @@ public: void setModeEdit(WorldEditorScene::ModeEdit mode); WorldEditorScene::ModeEdit editMode() const; - bool isEnabledEditPoint() const; + bool isEnabledEditPoints() const; + +Q_SIGNALS: + void selectionUpdated(const QList &selected, const QList &deselected); public Q_SLOTS: - void setEnabledEditPoint(bool enabled); + void setEnabledEditPoints(bool enabled); void updateSelection(const QList &selected, const QList &deselected); protected: @@ -79,25 +82,31 @@ protected: virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent); private: - QRectF calcBoundingRect(const QList &listItems); QPainterPath calcBoundingShape(const QList &listItems); - void updateSelectedItems(bool value); - void updateSelectedItem(QGraphicsItem *item, bool value); + + void updateSelectedWorldItems(bool value); + void updateSelectedWorldItem(QGraphicsItem *item, bool value); + void updateSelectedPointItems(bool value); + void updateSelectedPointItem(QGraphicsItem *item, bool value); void updatePickSelection(const QPointF &point); + void updatePickSelectionPoints(const QPointF &point); + + void checkUndo(); QPen m_pen1, m_pen2; QBrush m_brush1, m_brush2; - bool m_selectHack; QPointF m_firstPick, m_scaleFactor, m_pivot; QRectF m_selectionArea; qreal m_firstPickX, m_firstPickY, m_angle; QList m_selectedItems; + QList m_selectedPoints; + QList m_polygons; bool m_editedSelectedItems, m_firstSelection; uint m_lastPickedPrimitive; ModeEdit m_mode; - bool m_editMode; + bool m_pointsMode; QUndoStack *m_undoStack; PrimitivesTreeModel *m_model; }; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.cpp index 89ddd80a5..056a4f01e 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.cpp @@ -51,275 +51,41 @@ static QPainterPath qt_graphicsItem_shapeFromPath(const QPainterPath &path, cons p.addPath(path); return p; } -/* -GraphicsItemNode::GraphicsItemNode(GraphicsItemZone *itemZone, QGraphicsItem *parent) - : QGraphicsObject(parent) -{ - m_itemZone = itemZone; - m_color = QColor(12, 150, 215); - //setFlag(ItemIgnoresTransformations, true); - //setFlag(ItemClipsToShape); - - QPropertyAnimation *animation = new QPropertyAnimation(this, "colorNode"); - animation->setDuration(3000); - animation->setStartValue(QColor(10, 0, 50)); - animation->setKeyValueAt(0.5, QColor(155, 255, 0)); - animation->setEndValue(QColor(10, 0, 50)); - animation->setLoopCount(2000); - animation->setEasingCurve(QEasingCurve::OutInExpo); - animation->start(); - - setFlag(ItemIsSelectable); - setFlag(ItemIsMovable); - setFlag(ItemSendsScenePositionChanges); - m_type = EdgeType; - - setAcceptedMouseButtons(Qt::LeftButton | Qt::RightButton); - setZValue(10000000); -} - -GraphicsItemNode::~GraphicsItemNode() -{ -} - -void GraphicsItemNode::setColorNode(const QColor &color) -{ - m_color = color; - update(); -} - -void GraphicsItemNode::setNodeType(NodeType nodeType) -{ - m_type = nodeType; - if (m_type == EdgeType) - { - setFlag(ItemIsSelectable); - setFlag(ItemIsMovable); - setFlag(ItemSendsScenePositionChanges); - setAcceptedMouseButtons(Qt::LeftButton | Qt::RightButton); - setZValue(10000); - } - else if (m_type == MiddleType) - { - setFlag(ItemIsSelectable, false); - setFlag(ItemIsMovable, false); - setFlag(ItemSendsScenePositionChanges, false); - setAcceptedMouseButtons(Qt::LeftButton); - setZValue(10001); - } - update(); -} - -QRectF GraphicsItemNode::boundingRect() const -{ - return QRectF(QPointF(0, 0), QSizeF(20, 20)); -} - -void GraphicsItemNode::paint(QPainter *painter, - const QStyleOptionGraphicsItem *option, - QWidget *) -{ - // Here comes the magic: - //painter->setClipRect(option->exposedRect); - - painter->setPen(Qt::NoPen); - - if (m_type == EdgeType) - { - painter->setBrush(QColor(255, 0, 0)); - } - else if (m_type == MiddleType) - { - painter->setBrush(QColor(0, 0, 255)); - } - if (option->state & QStyle::State_Selected) - { - painter->setBrush(QColor(0, 255, 0)); - } - - painter->drawRect(2, 2, 18, 18); -} - -QVariant GraphicsItemNode::itemChange(GraphicsItemChange change, - const QVariant &value) -{ - if (change == ItemPositionHasChanged) - { - m_itemZone->updateZone(); - } - return QGraphicsItem::itemChange(change, value); -} - -void GraphicsItemNode::mousePressEvent(QGraphicsSceneMouseEvent *event) -{ - if ((m_type == MiddleType) && (event->button() == Qt::LeftButton)) - { - m_itemZone->updateMiddleNode(this); - setNodeType(EdgeType); - } - else if ((m_type == EdgeType) && (event->button() == Qt::RightButton)) - { - if (m_itemZone->deleteEdgePoint(this)) - setNodeType(MiddleType); - } -} - -GraphicsItemZone::GraphicsItemZone(QGraphicsScene *scene, QGraphicsItem *parent) - : QGraphicsPolygonItem(parent) -{ - m_scene = scene; - - m_color = QColor(12, 150, 215); - - setBrush(QBrush(QColor(100, 100, 255, 128))); - updateZone(); - setZValue(100); - //setFlag(ItemClipsToShape); - //setFlag(ItemIsSelectable, true); - //setFlag(ItemIsMovable, true); - //setFlag(ItemHasNoContents, true); -} -GraphicsItemZone::~GraphicsItemZone() +AbstractWorldItem::AbstractWorldItem(QGraphicsItem *parent) + : QGraphicsItem(parent), + m_active(false), + m_shapeChanged(false) { } -void GraphicsItemZone::updateMiddleNode(GraphicsItemNode *node) -{ - for (int i = 0; i < m_listLines.size(); ++i) - { - if (node == m_listLines.at(i).itemPoint) - { - LineItem oldLineItem = m_listLines[i]; - - GraphicsItemNode *newNode1 = new GraphicsItemNode(this); - newNode1->setPos((oldLineItem.lineNode.first->pos() + node->pos()) / 2); - newNode1->setNodeType(GraphicsItemNode::MiddleType); - m_scene->addItem(newNode1); - - GraphicsItemNode *newNode2 = new GraphicsItemNode(this); - newNode2->setPos((oldLineItem.lineNode.second->pos() + node->pos()) / 2); - newNode2->setNodeType(GraphicsItemNode::MiddleType); - m_scene->addItem(newNode2); - - LineItem newLineItem1; - newLineItem1.itemPoint = newNode1; - newLineItem1.lineNode = LineNode(oldLineItem.lineNode.first, node); - m_listLines.push_back(newLineItem1); - - LineItem newLineItem2; - newLineItem2.itemPoint = newNode2; - newLineItem2.lineNode = LineNode(node, oldLineItem.lineNode.second); - m_listLines.push_back(newLineItem2); - - m_listLines.removeAt(i); - - int pos = m_listItems.indexOf(oldLineItem.lineNode.second); - m_listItems.insert(pos, node); - - break; - } - } -} - -bool GraphicsItemZone::deleteEdgePoint(GraphicsItemNode *node) +AbstractWorldItem::~AbstractWorldItem() { - if (m_listItems.size() < 4) - return false; - - int pos = m_listItems.indexOf(node); - m_listItems.takeAt(pos); - - LineItem newLineItem; - - newLineItem.itemPoint = node; - - for (int i = 0; i < m_listLines.size(); ++i) - { - if (node == m_listLines.at(i).lineNode.first) - { - // Saving second point for new line - newLineItem.lineNode.second = m_listLines.at(i).lineNode.second; - delete m_listLines.at(i).itemPoint; - m_listLines.removeAt(i); - break; - } - } - - for (int i = 0; i < m_listLines.size(); ++i) - { - if (node == m_listLines.at(i).lineNode.second) - { - newLineItem.lineNode.first = m_listLines.at(i).lineNode.first; - delete m_listLines.at(i).itemPoint; - m_listLines.removeAt(i); - break; - } - } - node->setPos((newLineItem.lineNode.first->pos() + newLineItem.lineNode.second->pos()) / 2); - m_listLines.push_back(newLineItem); - - return true; } -void GraphicsItemZone::scanPolygon(const QPolygonF &polygon) +int AbstractWorldItem::type() const { - GraphicsItemNode *node1; - node1 = new GraphicsItemNode(this); - node1->setPos(*polygon.begin()); - m_listItems.push_back(node1); - m_scene->addItem(node1); - for (int i = 1; i < polygon.count(); ++i) - { - GraphicsItemNode *node2 = new GraphicsItemNode(this); - node2->setPos(polygon.at(i)); - m_listItems.push_back(node2); - - GraphicsItemNode *node3 = new GraphicsItemNode(this); - node3->setPos((node1->pos() + node2->pos()) / 2); - node3->setNodeType(GraphicsItemNode::MiddleType); - m_scene->addItem(node3); - - LineItem newLineItem; - newLineItem.itemPoint = node3; - newLineItem.lineNode = LineNode(node1, node2); - m_listLines.push_back(newLineItem); - - node1 = node2; - m_scene->addItem(node1); - } - setPolygon(polygon); + return Type; } -void GraphicsItemZone::updateZone() +void AbstractWorldItem::setActived(bool actived) { - QPolygonF polygon; - Q_FOREACH(GraphicsItemNode *node, m_listItems) - { - polygon << node->pos(); - } - - for (int i = 0; i < m_listLines.size(); ++i) - { - m_listLines.at(i).itemPoint->setPos((m_listLines.at(i).lineNode.first->pos() + m_listLines.at(i).lineNode.second->pos()) / 2); - } - - setPolygon(polygon); + m_active = actived; } -*/ -AbstractWorldItem::AbstractWorldItem(QGraphicsItem *parent) - : QGraphicsItem(parent) +bool AbstractWorldItem::isActived() const { + return m_active; } -AbstractWorldItem::~AbstractWorldItem() +void AbstractWorldItem::setShapeChanged(bool value) { + m_shapeChanged = value; } -int AbstractWorldItem::type() const +bool AbstractWorldItem::isShapeChanged() const { - return Type; + return m_shapeChanged; } WorldItemPoint::WorldItemPoint(const QPointF &point, const qreal angle, const qreal radius, @@ -360,7 +126,6 @@ WorldItemPoint::WorldItemPoint(const QPointF &point, const qreal angle, const qr } updateBoundingRect(); - //setFlag(ItemIsSelectable); } WorldItemPoint::~WorldItemPoint() @@ -373,9 +138,7 @@ void WorldItemPoint::rotateOn(const QPointF &pivot, const qreal deltaAngle) QPolygonF rotatedPolygon(m_rect); - // TODO rotatedPolygon.translate(pos() - pivot); - //rotatedPolygon.translate(-pivot); QTransform trans; trans = trans.rotate(deltaAngle); @@ -391,9 +154,7 @@ void WorldItemPoint::scaleOn(const QPointF &pivot, const QPointF &factor) QPolygonF scaledPolygon(m_rect); - // TODO scaledPolygon.translate(pos() - pivot); - //scaledPolygon.translate(-pivot); QTransform trans; trans = trans.scale(factor.x(), factor.y()); @@ -478,7 +239,8 @@ void WorldItemPoint::paint(QPainter *painter, const QStyleOptionGraphicsItem *op painter->drawLines(m_arrow); painter->setPen(Qt::NoPen); - if (option->state & QStyle::State_Selected) +// if (option->state & QStyle::State_Selected) + if (isActived()) painter->setBrush(m_selectedBrush); else painter->setBrush(m_brush); @@ -487,17 +249,10 @@ void WorldItemPoint::paint(QPainter *painter, const QStyleOptionGraphicsItem *op painter->drawRect(m_rect); } -QVariant WorldItemPoint::itemChange(GraphicsItemChange change, const QVariant &value) -{ - if (change == ItemPositionHasChanged) - { - } - return QGraphicsItem::itemChange(change, value); -} - WorldItemPath::WorldItemPath(const QPolygonF &polygon, QGraphicsItem *parent) : AbstractWorldItem(parent), - m_polygon(polygon) + m_polygon(polygon), + m_pointEdit(false) { //setFlag(ItemIsSelectable); @@ -548,17 +303,142 @@ void WorldItemPath::scaleOn(const QPointF &pivot, const QPointF &factor) m_polygon.translate(pivot - pos()); } -void WorldItemPath::turnOn(const qreal angle) +void WorldItemPath::setColor(const QColor &color) { + m_pen.setColor(color); } -void WorldItemPath::radiusOn(const qreal radius) + +void WorldItemPath::setEnabledSubPoints(bool enabled) { + m_pointEdit = enabled; + if (m_pointEdit) + createSubPoints(); + else + removeSubPoints(); } -void WorldItemPath::setColor(const QColor &color) +void WorldItemPath::moveSubPoint(WorldItemSubPoint *subPoint) { - m_pen.setColor(color); + prepareGeometryChange(); + + QPolygonF polygon; + + // Update polygon + Q_FOREACH(WorldItemSubPoint *node, m_listItems) + { + polygon << node->pos(); + } + + // Update middle points + for (int i = 0; i < m_listLines.size(); ++i) + m_listLines.at(i).itemPoint->setPos((m_listLines.at(i).lineItem.first->pos() + m_listLines.at(i).lineItem.second->pos()) / 2); + + m_polygon = polygon; + update(); +} + +void WorldItemPath::addSubPoint(WorldItemSubPoint *subPoint) +{ + prepareGeometryChange(); + + for (int i = 0; i < m_listLines.size(); ++i) + { + if (subPoint == m_listLines.at(i).itemPoint) + { + LineStruct oldLineItem = m_listLines[i]; + + // Create the first middle sub-point + WorldItemSubPoint *firstItem = new WorldItemSubPoint(WorldItemSubPoint::MiddleType, this); + firstItem->setPos((oldLineItem.lineItem.first->pos() + subPoint->pos()) / 2); + + // Create the second middle sub-point + WorldItemSubPoint *secondItem = new WorldItemSubPoint(WorldItemSubPoint::MiddleType, this); + secondItem->setPos((oldLineItem.lineItem.second->pos() + subPoint->pos()) / 2); + + // Add first line in the list + LineStruct firstNewLineItem; + firstNewLineItem.itemPoint = firstItem; + firstNewLineItem.lineItem = LineItem(oldLineItem.lineItem.first, subPoint); + m_listLines.push_back(firstNewLineItem); + + // Add second line in the list + LineStruct secondNewLineItem; + secondNewLineItem.itemPoint = secondItem; + secondNewLineItem.lineItem = LineItem(subPoint, oldLineItem.lineItem.second); + m_listLines.push_back(secondNewLineItem); + + m_listLines.removeAt(i); + + int pos = m_listItems.indexOf(oldLineItem.lineItem.second); + m_listItems.insert(pos, subPoint); + subPoint->setFlag(ItemSendsScenePositionChanges); + + break; + } + } +} + +bool WorldItemPath::removeSubPoint(WorldItemSubPoint *subPoint) +{ + int pos = m_listItems.indexOf(subPoint); + + // First and second points can not be removed + if ((pos == 0) || (pos == m_listItems.size() - 1)) + return false; + + prepareGeometryChange(); + + m_listItems.takeAt(pos); + + LineStruct newLineItem; + + newLineItem.itemPoint = subPoint; + + // Delete first line + for (int i = 0; i < m_listLines.size(); ++i) + { + if (subPoint == m_listLines.at(i).lineItem.first) + { + // Saving second point for new line + newLineItem.lineItem.second = m_listLines.at(i).lineItem.second; + delete m_listLines.at(i).itemPoint; + m_listLines.removeAt(i); + break; + } + } + + // Delete second line + for (int i = 0; i < m_listLines.size(); ++i) + { + if (subPoint == m_listLines.at(i).lineItem.second) + { + // Saving first point for new line + newLineItem.lineItem.first = m_listLines.at(i).lineItem.first; + delete m_listLines.at(i).itemPoint; + m_listLines.removeAt(i); + break; + } + } + subPoint->setPos((newLineItem.lineItem.first->pos() + newLineItem.lineItem.second->pos()) / 2); + m_listLines.push_back(newLineItem); + subPoint->setFlag(ItemSendsScenePositionChanges, false); + + return true; +} + +void WorldItemPath::setPolygon(const QPolygonF &polygon) +{ + prepareGeometryChange(); + + m_polygon = polygon; + + update(); +} + +QPolygonF WorldItemPath::polygon() const +{ + return m_polygon; } QPainterPath WorldItemPath::shape() const @@ -582,7 +462,8 @@ void WorldItemPath::paint(QPainter *painter, const QStyleOptionGraphicsItem *opt // Here comes the magic: //painter->setClipRect(option->exposedRect); - if (option->state & QStyle::State_Selected) + //if (option->state & QStyle::State_Selected) + if (isActived()) painter->setPen(m_selectedPen); else painter->setPen(m_pen); @@ -590,17 +471,49 @@ void WorldItemPath::paint(QPainter *painter, const QStyleOptionGraphicsItem *opt painter->drawPolyline(m_polygon); } -QVariant WorldItemPath::itemChange(GraphicsItemChange change, const QVariant &value) +void WorldItemPath::createSubPoints() { - if (change == ItemPositionHasChanged) + WorldItemSubPoint *firstPoint; + firstPoint = new WorldItemSubPoint(WorldItemSubPoint::EdgeType, this); + firstPoint->setPos(m_polygon.front()); + firstPoint->setFlag(ItemSendsScenePositionChanges); + m_listItems.push_back(firstPoint); + + for (int i = 1; i < m_polygon.count(); ++i) { + WorldItemSubPoint *secondPoint = new WorldItemSubPoint(WorldItemSubPoint::EdgeType, this); + secondPoint->setPos(m_polygon.at(i)); + secondPoint->setFlag(ItemSendsScenePositionChanges); + + WorldItemSubPoint *middlePoint = new WorldItemSubPoint(WorldItemSubPoint::MiddleType, this); + middlePoint->setPos((firstPoint->pos() + secondPoint->pos()) / 2); + + LineStruct newLineItem; + newLineItem.itemPoint = middlePoint; + newLineItem.lineItem = LineItem(firstPoint, secondPoint); + m_listLines.push_back(newLineItem); + + firstPoint = secondPoint; + m_listItems.push_back(firstPoint); } - return QGraphicsItem::itemChange(change, value); +} + +void WorldItemPath::removeSubPoints() +{ + for (int i = 0; i < m_listLines.count(); ++i) + delete m_listLines.at(i).itemPoint; + + for (int i = 0; i < m_listItems.count(); ++i) + delete m_listItems.at(i); + + m_listItems.clear(); + m_listLines.clear(); } WorldItemZone::WorldItemZone(const QPolygonF &polygon, QGraphicsItem *parent) : AbstractWorldItem(parent), - m_polygon(polygon) + m_polygon(polygon), + m_pointEdit(false) { //setFlag(ItemIsSelectable); @@ -646,7 +559,6 @@ void WorldItemZone::scaleOn(const QPointF &pivot, const QPointF &factor) prepareGeometryChange(); QPolygonF scaledPolygon(m_polygon); - scaledPolygon.translate(pos() - pivot); QTransform trans; @@ -656,22 +568,151 @@ void WorldItemZone::scaleOn(const QPointF &pivot, const QPointF &factor) m_polygon.translate(pivot - pos()); } -void WorldItemZone::turnOn(const qreal angle) +void WorldItemZone::setColor(const QColor &color) { + m_pen.setColor(color); + + QColor brushColor(color); + brushColor.setAlpha(TRANSPARENCY); + + m_brush.setColor(brushColor); } -void WorldItemZone::radiusOn(const qreal radius) +void WorldItemZone::setEnabledSubPoints(bool enabled) { + m_pointEdit = enabled; + if (m_pointEdit) + createSubPoints(); + else + removeSubPoints(); + + setShapeChanged(false); } -void WorldItemZone::setColor(const QColor &color) +void WorldItemZone::moveSubPoint(WorldItemSubPoint *subPoint) { - m_pen.setColor(color); + prepareGeometryChange(); - QColor brushColor(color); - brushColor.setAlpha(TRANSPARENCY); + QPolygonF polygon; - m_brush.setColor(brushColor); + // Update polygon + Q_FOREACH(WorldItemSubPoint *node, m_listItems) + { + polygon << node->pos(); + } + + // Update middle points + for (int i = 0; i < m_listLines.size(); ++i) + m_listLines.at(i).itemPoint->setPos((m_listLines.at(i).lineItem.first->pos() + m_listLines.at(i).lineItem.second->pos()) / 2); + + m_polygon = polygon; + update(); + + setShapeChanged(true); +} + +void WorldItemZone::addSubPoint(WorldItemSubPoint *subPoint) +{ + prepareGeometryChange(); + + for (int i = 0; i < m_listLines.size(); ++i) + { + if (subPoint == m_listLines.at(i).itemPoint) + { + LineStruct oldLineItem = m_listLines[i]; + + // Create the first middle sub-point + WorldItemSubPoint *firstItem = new WorldItemSubPoint(WorldItemSubPoint::MiddleType, this); + firstItem->setPos((oldLineItem.lineItem.first->pos() + subPoint->pos()) / 2); + + // Create the second middle sub-point + WorldItemSubPoint *secondItem = new WorldItemSubPoint(WorldItemSubPoint::MiddleType, this); + secondItem->setPos((oldLineItem.lineItem.second->pos() + subPoint->pos()) / 2); + + // Add first line in the list + LineStruct firstNewLineItem; + firstNewLineItem.itemPoint = firstItem; + firstNewLineItem.lineItem = LineItem(oldLineItem.lineItem.first, subPoint); + m_listLines.push_back(firstNewLineItem); + + // Add second line in the list + LineStruct secondNewLineItem; + secondNewLineItem.itemPoint = secondItem; + secondNewLineItem.lineItem = LineItem(subPoint, oldLineItem.lineItem.second); + m_listLines.push_back(secondNewLineItem); + + m_listLines.removeAt(i); + + int pos = m_listItems.indexOf(oldLineItem.lineItem.second); + m_listItems.insert(pos, subPoint); + subPoint->setFlag(ItemSendsScenePositionChanges); + + break; + } + } + setShapeChanged(true); +} + +bool WorldItemZone::removeSubPoint(WorldItemSubPoint *subPoint) +{ + prepareGeometryChange(); + + if (m_listItems.size() < 4) + return false; + + int pos = m_listItems.indexOf(subPoint); + m_listItems.takeAt(pos); + + LineStruct newLineItem; + + newLineItem.itemPoint = subPoint; + + // Delete first line + for (int i = 0; i < m_listLines.size(); ++i) + { + if (subPoint == m_listLines.at(i).lineItem.first) + { + // Saving second point for new line + newLineItem.lineItem.second = m_listLines.at(i).lineItem.second; + delete m_listLines.at(i).itemPoint; + m_listLines.removeAt(i); + break; + } + } + + // Delete second line + for (int i = 0; i < m_listLines.size(); ++i) + { + if (subPoint == m_listLines.at(i).lineItem.second) + { + // Saving first point for new line + newLineItem.lineItem.first = m_listLines.at(i).lineItem.first; + delete m_listLines.at(i).itemPoint; + m_listLines.removeAt(i); + break; + } + } + m_listLines.push_back(newLineItem); + subPoint->setPos((newLineItem.lineItem.first->pos() + newLineItem.lineItem.second->pos()) / 2); + subPoint->setFlag(ItemSendsScenePositionChanges, false); + + setShapeChanged(true); + + return true; +} + +void WorldItemZone::setPolygon(const QPolygonF &polygon) +{ + prepareGeometryChange(); + + m_polygon = polygon; + + update(); +} + +QPolygonF WorldItemZone::polygon() const +{ + return m_polygon; } QRectF WorldItemZone::boundingRect() const @@ -688,7 +729,8 @@ QPainterPath WorldItemZone::shape() const void WorldItemZone::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *) { - if (option->state & QStyle::State_Selected) +// if (option->state & QStyle::State_Selected) + if (isActived()) { painter->setPen(m_selectedPen); painter->setBrush(m_selectedBrush); @@ -702,12 +744,192 @@ void WorldItemZone::paint(QPainter *painter, const QStyleOptionGraphicsItem *opt painter->drawPolygon(m_polygon); } -QVariant WorldItemZone::itemChange(GraphicsItemChange change, const QVariant &value) +void WorldItemZone::createSubPoints() { - if (change == ItemPositionHasChanged) + WorldItemSubPoint *firstPoint; + firstPoint = new WorldItemSubPoint(WorldItemSubPoint::EdgeType, this); + firstPoint->setPos(m_polygon.front()); + firstPoint->setFlag(ItemSendsScenePositionChanges); + m_listItems.push_back(firstPoint); + + for (int i = 1; i < m_polygon.count(); ++i) + { + WorldItemSubPoint *secondPoint = new WorldItemSubPoint(WorldItemSubPoint::EdgeType, this); + secondPoint->setPos(m_polygon.at(i)); + secondPoint->setFlag(ItemSendsScenePositionChanges); + + WorldItemSubPoint *middlePoint = new WorldItemSubPoint(WorldItemSubPoint::MiddleType, this); + middlePoint->setPos((firstPoint->pos() + secondPoint->pos()) / 2); + + LineStruct newLineItem; + newLineItem.itemPoint = middlePoint; + newLineItem.lineItem = LineItem(firstPoint, secondPoint); + m_listLines.push_back(newLineItem); + + firstPoint = secondPoint; + m_listItems.push_back(firstPoint); + } + + LineStruct endLineItem; + endLineItem.itemPoint = new WorldItemSubPoint(WorldItemSubPoint::MiddleType, this); + endLineItem.itemPoint->setPos((m_listItems.first()->pos() + m_listItems.last()->pos()) / 2); + endLineItem.lineItem = LineItem(m_listItems.last(), m_listItems.first()); + m_listLines.push_back(endLineItem); +} + +void WorldItemZone::removeSubPoints() +{ + for (int i = 0; i < m_listLines.count(); ++i) + delete m_listLines.at(i).itemPoint; + + for (int i = 0; i < m_listItems.count(); ++i) + delete m_listItems.at(i); + + m_listItems.clear(); + m_listLines.clear(); +} + +//******************************************* + +WorldItemSubPoint::WorldItemSubPoint(SubPointType pointType, AbstractWorldItem *parent) + : QGraphicsObject(parent), + m_type(pointType), + m_active(false), + m_parent(parent) +{ + setZValue(WORLD_POINT_LAYER); + + m_brush.setColor(QColor(20, 100, 255)); + m_brush.setStyle(Qt::SolidPattern); + + m_brushMiddle.setColor(QColor(255, 25, 100)); + m_brushMiddle.setStyle(Qt::SolidPattern); + + m_selectedBrush.setColor(QColor(255, 255, 255, 100)); + m_selectedBrush.setStyle(Qt::SolidPattern); + + m_rect.setCoords(-SIZE_POINT, -SIZE_POINT, SIZE_POINT, SIZE_POINT); + updateBoundingRect(); + + //setFlag(ItemIgnoresTransformations); + //setFlag(ItemSendsScenePositionChanges); +} + +WorldItemSubPoint::~WorldItemSubPoint() +{ +} + +void WorldItemSubPoint::setSubPointType(SubPointType nodeType) +{ + m_type = nodeType; + setFlag(ItemSendsScenePositionChanges); +} + +WorldItemSubPoint::SubPointType WorldItemSubPoint::subPointType() const +{ + return m_type; +} + +void WorldItemSubPoint::rotateOn(const QPointF &pivot, const qreal deltaAngle) +{ + prepareGeometryChange(); + + QPolygonF rotatedPolygon(m_rect); + + // TODO + rotatedPolygon.translate(scenePos() - pivot); + + QTransform trans; + trans = trans.rotate(deltaAngle); + rotatedPolygon = trans.map(rotatedPolygon); + rotatedPolygon.translate(pivot); + + setPos(m_parent->mapFromParent(rotatedPolygon.boundingRect().center())); +} + +void WorldItemSubPoint::scaleOn(const QPointF &pivot, const QPointF &factor) +{ + prepareGeometryChange(); + + QPolygonF scaledPolygon(m_rect); + + // TODO + scaledPolygon.translate(scenePos() - pivot); + //scaledPolygon.translate(-pivot); + + QTransform trans; + trans = trans.scale(factor.x(), factor.y()); + scaledPolygon = trans.map(scaledPolygon); + scaledPolygon.translate(pivot); + + setPos(m_parent->mapFromParent(scaledPolygon.boundingRect().center())); +} + +QRectF WorldItemSubPoint::boundingRect() const +{ + return m_boundingRect; +} + +void WorldItemSubPoint::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + painter->setPen(Qt::NoPen); + + if (m_type == WorldItemSubPoint::EdgeType) { + if (isActived()) + painter->setBrush(m_selectedBrush); + else + painter->setBrush(m_brush); } + else + { + painter->setBrush(m_brushMiddle); + } + + // Draw point + painter->drawRect(m_rect); +} + +int WorldItemSubPoint::type() const +{ + return Type; +} + +void WorldItemSubPoint::setActived(bool actived) +{ + m_active = actived; +} + +bool WorldItemSubPoint::isActived() const +{ + return m_active; +} + +QVariant WorldItemSubPoint::itemChange(GraphicsItemChange change, const QVariant &value) +{ + if (change == ItemPositionHasChanged) + m_parent->moveSubPoint(this); return QGraphicsItem::itemChange(change, value); } +void WorldItemSubPoint::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + if ((m_type == MiddleType) && (event->button() == Qt::LeftButton)) + { + m_parent->addSubPoint(this); + setSubPointType(EdgeType); + } + else if ((m_type == EdgeType) && (event->button() == Qt::RightButton)) + { + if (m_parent->removeSubPoint(this)) + setSubPointType(MiddleType); + } + update(); +} + +void WorldItemSubPoint::updateBoundingRect() +{ + m_boundingRect.setCoords(-SIZE_POINT, -SIZE_POINT, SIZE_POINT, SIZE_POINT); +} + } /* namespace WorldEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h index 0625084bd..1b934d77b 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h @@ -32,10 +32,15 @@ namespace WorldEditor { -class GraphicsItemZone; -class GraphicsItemNode; +class WorldItemSubPoint; -typedef QPair LineNode; +typedef QPair LineItem; + +struct LineStruct +{ + WorldItemSubPoint *itemPoint; + LineItem lineItem; +}; const int SELECTED_LAYER = 200; const int UNSELECTED_LAYER = 100; @@ -46,75 +51,6 @@ const int MIDDLE_POINT_LAYER = 201; const int EDGE_POINT_LAYER = 201; const int SIZE_ARROW = 20; -/* -// Deprecated -class GraphicsItemNode: public QGraphicsObject -{ - Q_OBJECT - Q_PROPERTY(QColor colorNode READ colorNode WRITE setColorNode) -public: - enum NodeType - { - EdgeType = 0, - MiddleType - }; - - GraphicsItemNode(GraphicsItemZone *itemZone, QGraphicsItem *parent = 0); - virtual ~GraphicsItemNode(); - - void setColorNode(const QColor &color); - QColor colorNode() const - { - return m_color; - } - - void setNodeType(NodeType nodeType); - - virtual QRectF boundingRect() const; - //QPainterPath shape() const; - virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); - -protected: - virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value); - virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); - -private: - - NodeType m_type; - GraphicsItemZone *m_itemZone; - QColor m_color; -}; - -// Deprecated -class GraphicsItemZone: public QGraphicsPolygonItem -{ -public: - GraphicsItemZone(QGraphicsScene *scene, QGraphicsItem *parent = 0); - virtual ~GraphicsItemZone(); - - void scanPolygon(const QPolygonF &polygon); - void updateMiddleNode(GraphicsItemNode *node); - bool deleteEdgePoint(GraphicsItemNode *node); - //void addNode(GraphicsItemNode *node); - void updateZone(); - //QRectF boundingRect() const; - //void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); - -protected: - // QVariant itemChange(GraphicsItemChange change, const QVariant &value); - -private: - struct LineItem - { - GraphicsItemNode *itemPoint; - LineNode lineNode; - }; - QGraphicsScene *m_scene; - QColor m_color; - QList m_listItems; - QList m_listLines; -}; -*/ /* @class WorldItemPoint @@ -129,16 +65,40 @@ public: enum { Type = QGraphicsItem::UserType + 1 }; - virtual void rotateOn(const QPointF &pivot, const qreal deltaAngle) = 0; + virtual void rotateOn(const QPointF &pivot, const qreal deltaAngle) {}; // TODO: add modes: IgnoreAspectRatio, KeepAspectRatio - virtual void scaleOn(const QPointF &pivot, const QPointF &factor) = 0; - virtual void turnOn(const qreal angle) = 0; - virtual void radiusOn(const qreal radius) = 0; + virtual void scaleOn(const QPointF &pivot, const QPointF &factor) {}; + virtual void turnOn(const qreal angle) {}; + virtual void radiusOn(const qreal radius) {}; virtual void setColor(const QColor &color) = 0; + virtual void setEnabledSubPoints(bool enabled) = 0; + + virtual void moveSubPoint(WorldItemSubPoint *subPoint) {} + virtual void addSubPoint(WorldItemSubPoint *subPoint) {} + virtual bool removeSubPoint(WorldItemSubPoint *subPoint) + { + return false; + } + + virtual void setPolygon(const QPolygonF &polygon) {} + virtual QPolygonF polygon() const + { + return QPolygonF(); + } + + void setActived(bool actived); + bool isActived() const; + + void setShapeChanged(bool value); + bool isShapeChanged() const; // Enable the use of qgraphicsitem_cast with this item. int type() const; + +protected: + + bool m_active, m_shapeChanged; }; /* @@ -159,19 +119,16 @@ public: virtual void radiusOn(const qreal radius); virtual void setColor(const QColor &color); + virtual void setEnabledSubPoints(bool enabled) {} virtual QRectF boundingRect() const; virtual QPainterPath shape() const; virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); -protected: - virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value); - private: void createCircle(); void updateBoundingRect(); - // TODO static const int SIZE_POINT = 3; QPen m_pen, m_selectedPen; @@ -197,20 +154,31 @@ public: virtual void rotateOn(const QPointF &pivot, const qreal deltaAngle); virtual void scaleOn(const QPointF &pivot, const QPointF &factor); - virtual void turnOn(const qreal angle); - virtual void radiusOn(const qreal radius); virtual void setColor(const QColor &color); + virtual void setEnabledSubPoints(bool enabled); + + virtual void moveSubPoint(WorldItemSubPoint *subPoint); + virtual void addSubPoint(WorldItemSubPoint *subPoint); + virtual bool removeSubPoint(WorldItemSubPoint *subPoint); + + virtual void setPolygon(const QPolygonF &polygon); + virtual QPolygonF polygon() const; virtual QRectF boundingRect() const; virtual QPainterPath shape() const; virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); -protected: - virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value); +private: + void createSubPoints(); + void removeSubPoints(); QPen m_pen, m_selectedPen; QPolygonF m_polygon; + bool m_pointEdit; + + QList m_listItems; + QList m_listLines; }; /* @@ -226,27 +194,91 @@ public: virtual void rotateOn(const QPointF &pivot, const qreal deltaAngle); virtual void scaleOn(const QPointF &pivot, const QPointF &factor); - virtual void turnOn(const qreal angle); - virtual void radiusOn(const qreal radius); virtual void setColor(const QColor &color); + virtual void setEnabledSubPoints(bool enabled); + + virtual void moveSubPoint(WorldItemSubPoint *subPoint); + virtual void addSubPoint(WorldItemSubPoint *subPoint); + virtual bool removeSubPoint(WorldItemSubPoint *subPoint); + + virtual void setPolygon(const QPolygonF &polygon); + virtual QPolygonF polygon() const; virtual QRectF boundingRect() const; virtual QPainterPath shape() const; virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); -protected: - virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value); +private: + void createSubPoints(); + void removeSubPoints(); static const int TRANSPARENCY = 38; QPen m_pen, m_selectedPen; QBrush m_brush, m_selectedBrush; QPolygonF m_polygon; + bool m_pointEdit; + + QList m_listItems; + QList m_listLines; +}; + +/* +@class WorldItemSubPoint +@brief +@details +*/ +class WorldItemSubPoint: public QGraphicsObject +{ + Q_OBJECT +public: + enum SubPointType + { + EdgeType = 0, + MiddleType + }; + + enum { Type = QGraphicsItem::UserType + 2 }; + + WorldItemSubPoint(SubPointType pointType, AbstractWorldItem *parent = 0); + virtual ~WorldItemSubPoint(); + + void setSubPointType(SubPointType nodeType); + SubPointType subPointType() const; + + void rotateOn(const QPointF &pivot, const qreal deltaAngle); + void scaleOn(const QPointF &pivot, const QPointF &factor); + + virtual QRectF boundingRect() const; + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + + void setActived(bool actived); + bool isActived() const; + + // Enable the use of qgraphicsitem_cast with this item. + int type() const; + +protected: + virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value); + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + +private: + void updateBoundingRect(); + + static const int SIZE_POINT = 6; + + QBrush m_brush, m_brushMiddle, m_selectedBrush; + + QRectF m_rect, m_boundingRect; + SubPointType m_type; + bool m_active; + AbstractWorldItem *m_parent; }; } /* namespace WorldEditor */ +// Enable the use of QVariant with this class. Q_DECLARE_METATYPE(WorldEditor::AbstractWorldItem *) #endif // WORLD_EDITOR_SCENE_ITEM_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp index e00e804f3..009ede2e1 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp @@ -98,7 +98,7 @@ WorldEditorWindow::WorldEditorWindow(QWidget *parent) m_modeMapper->setMapping(m_ui.radiusAction, 5); connect(m_modeMapper, SIGNAL(mapped(int)), this, SLOT(setMode(int))); - connect(m_ui.pointsAction, SIGNAL(triggered(bool)), m_worldEditorScene, SLOT(setEnabledEditPoint(bool))); + connect(m_ui.pointsAction, SIGNAL(triggered(bool)), m_worldEditorScene, SLOT(setEnabledEditPoints(bool))); connect(m_ui.settingsAction, SIGNAL(triggered()), this, SLOT(openProjectSettings())); connect(m_ui.newWorldEditAction, SIGNAL(triggered()), this, SLOT(newWorldEditFile())); @@ -256,6 +256,7 @@ void WorldEditorWindow::updateStatusBar() void WorldEditorWindow::updateSelection(const QItemSelection &selected, const QItemSelection &deselected) { m_ui.pointsAction->setChecked(false); + m_worldEditorScene->setEnabledEditPoints(false); NodeList nodesSelected; Q_FOREACH(QModelIndex modelIndex, selected.indexes()) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui index c556514b7..1de6cbdc3 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui @@ -37,7 +37,7 @@ QGraphicsView::AnchorUnderMouse - QGraphicsView::BoundingRectViewportUpdate + QGraphicsView::FullViewportUpdate QGraphicsView::DontAdjustForAntialiasing|QGraphicsView::DontClipPainter @@ -129,6 +129,15 @@ + + + Property Editor + + + 2 + + + loadPrimitive @@ -319,7 +328,7 @@ true - false + true Edit points @@ -346,6 +355,12 @@ QTreeView
primitives_view.h
+ + WorldEditor::PropertyEditorWidget + QWidget +
property_editor_widget.h
+ 1 +
From 434ce9d6a9e980b82de3a41c700ce3d0c6a01735 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Mon, 15 Aug 2011 17:04:09 +0300 Subject: [PATCH 57/89] Changed: #1302 Added empty property dialog. --HG-- branch : gsoc2011-worldeditorqt --- .../src/plugins/world_editor/CMakeLists.txt | 16 ++++- .../world_editor/property_editor_widget.cpp | 60 ++++++++++++++++++ .../world_editor/property_editor_widget.h | 63 +++++++++++++++++++ .../world_editor/property_editor_widget.ui | 40 ++++++++++++ 4 files changed, 177 insertions(+), 2 deletions(-) create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.cpp create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.h create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.ui diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/CMakeLists.txt index 7b9387c44..694467f42 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/CMakeLists.txt +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/CMakeLists.txt @@ -1,7 +1,9 @@ INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ${LIBXML2_INCLUDE_DIR} - ${QT_INCLUDES}) + ${QT_INCLUDES} + ${CMAKE_CURRENT_SOURCE_DIR}/../../3rdparty/qtpropertybrowser + ) FILE(GLOB SRC *.cpp *.h) @@ -16,11 +18,13 @@ SET(OVQT_PLUGIN_WORLD_EDITOR_HDR world_editor_plugin.h primitives_model.h primitives_view.h project_settings_dialog.h + property_editor_widget.h world_editor_settings_page.h ) SET(OVQT_PLUGIN_WORLD_EDITOR_UIS world_editor_window.ui project_settings_dialog.ui + property_editor_widget.ui world_editor_settings_page.ui ) @@ -45,7 +49,15 @@ ADD_LIBRARY(ovqt_plugin_world_editor MODULE ${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}) +TARGET_LINK_LIBRARIES( ovqt_plugin_world_editor + ovqt_plugin_core + ovqt_plugin_landscape_editor + nelmisc + nel3d + qt_property_browser + ${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) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.cpp new file mode 100644 index 000000000..7df0b6d1d --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.cpp @@ -0,0 +1,60 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +// Project includes +#include "property_editor_widget.h" + +// NeL includes +#include + +// STL includes +#include +#include + +// Qt includes +#include + +namespace WorldEditor +{ + +PropertyEditorWidget::PropertyEditorWidget(QWidget *parent) + : QWidget(parent) +{ + m_ui.setupUi(this); + + m_variantManager = new QtVariantPropertyManager(this); + + connect(m_variantManager, SIGNAL(valueChanged(QtProperty *, const QVariant &)), + this, SLOT(valueChanged(QtProperty *, const QVariant &))); + + QtVariantEditorFactory *variantFactory = new QtVariantEditorFactory(this); + m_ui.treePropertyBrowser->setFactoryForManager(m_variantManager, variantFactory); +} + +PropertyEditorWidget::~PropertyEditorWidget() +{ +} + +void PropertyEditorWidget::clearProperties() +{ +} + +void PropertyEditorWidget::setCurrentPrimitive(PrimitiveNode *node) +{ +} + +} /* namespace WorldEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.h new file mode 100644 index 000000000..18f72fadc --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.h @@ -0,0 +1,63 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// 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 . + +#ifndef PROPERTY_EDITOR_WIDGET_H +#define PROPERTY_EDITOR_WIDGET_H + +// Project includes +#include "ui_property_editor_widget.h" +#include "primitives_model.h" +#include "primitive_item.h" + + +// 3rdparty +#include "qtvariantproperty.h" +#include "qtpropertymanager.h" +#include "qteditorfactory.h" + +// NeL includes + +// Qt includes + +namespace WorldEditor +{ +/** +@class PropertyEditorWidget +@brief PropertyEditorWidget +@details +*/ +class PropertyEditorWidget: public QWidget +{ + Q_OBJECT + +public: + PropertyEditorWidget(QWidget *parent = 0); + ~PropertyEditorWidget(); + +public Q_SLOTS: + void clearProperties(); + void setCurrentPrimitive(PrimitiveNode *node); + +private: + + QtVariantPropertyManager *m_variantManager; + Ui::PropertyEditorWidget m_ui; +}; /* PropertyEditorWidget */ + +} /* namespace WorldEditor */ + +#endif // PROPERTY_EDITOR_WIDGET_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.ui new file mode 100644 index 000000000..a703c7aac --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.ui @@ -0,0 +1,40 @@ + + + PropertyEditorWidget + + + + 0 + 0 + 183 + 128 + + + + Form + + + + 3 + + + 3 + + + + + + + + + QtTreePropertyBrowser + QWidget +
qttreepropertybrowser.h
+ 1 +
+
+ + + + +
From 054e5c521cd92fd68db2e5d560f97c5734c7c9bd Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Tue, 16 Aug 2011 01:10:22 +0300 Subject: [PATCH 58/89] Changed: #1302 When create zone or path initially has minimal 3 points and path 2 points resp. --HG-- branch : gsoc2011-worldeditorqt --- .../world_editor/world_editor_actions.cpp | 19 ++++++++--- .../world_editor/world_editor_actions.h | 2 ++ .../world_editor/world_editor_misc.cpp | 18 +++++++++-- .../world_editor/world_editor_scene_item.cpp | 6 +++- .../world_editor/world_editor_scene_item.h | 2 +- .../world_editor/world_editor_window.ui | 32 +++++++++++++++---- 6 files changed, 64 insertions(+), 15 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp index 45adf49ce..f40e498a1 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp @@ -38,6 +38,7 @@ // Qt includes #include +#include #include namespace WorldEditor @@ -365,6 +366,13 @@ AddPrimitiveByClassCommand::AddPrimitiveByClassCommand(const QString &className, m_model(model) { setText(QString("Add %1").arg(m_className)); + + QGraphicsView *view = m_scene->views().first(); + + // TODO: returns incorrect position when zoom in + QRectF visibleArea = view->mapToScene(view->rect()).boundingRect(); + m_delta = visibleArea.height() / 10.0; + m_initPos = visibleArea.center(); } AddPrimitiveByClassCommand::~AddPrimitiveByClassCommand() @@ -381,6 +389,8 @@ void AddPrimitiveByClassCommand::undo() // set the primitive context NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = node->rootPrimitiveNode()->primitives(); + removeGraphicsItems(index, m_model, m_scene); + Utils::deletePrimitive(node->primitive()); // unset the context @@ -397,7 +407,6 @@ void AddPrimitiveByClassCommand::redo() PrimitiveNode *parentNode = static_cast(parentIndex.internalPointer()); const NLLIGO::CPrimitiveClass *primClass = parentNode->primitiveClass(); - float delta = 10; int id = 0; while (primClass->DynamicChildren[id].ClassName != m_className.toStdString()) ++id; @@ -407,12 +416,14 @@ void AddPrimitiveByClassCommand::redo() 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()); + NLMISC::CVector(m_initPos.x(), -m_initPos.y(), 0.0), m_delta, primClass->DynamicChildren[id].Parameters, parentNode->primitive()); // unset the context NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = NULL; m_newPrimIndex = m_model->createPrimitiveNode(newPrimitive, m_parentIndex); + + addNewGraphicsItems(m_model->pathToIndex(m_newPrimIndex), m_model, m_scene); } MoveWorldItemsCommand::MoveWorldItemsCommand(const QList &items, const QPointF &offset, @@ -471,7 +482,7 @@ RotateWorldItemsCommand::RotateWorldItemsCommand(const QList &i m_scene(scene), m_firstRun(true) { - setText(QString("Rotate item(s) %1").arg(m_angle)); + setText("Rotate item(s)"); } RotateWorldItemsCommand::~RotateWorldItemsCommand() @@ -565,7 +576,7 @@ TurnWorldItemsCommand::TurnWorldItemsCommand(const QList &items m_scene(scene), m_firstRun(true) { - setText(QString("Turn item(s) %1").arg(m_angle)); + setText("Turn item(s)"); } TurnWorldItemsCommand::~TurnWorldItemsCommand() diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h index fcb510605..a8352e2e6 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h @@ -147,6 +147,8 @@ public: virtual void redo(); private: + QPointF m_initPos; + float m_delta; const QString m_className; Path m_parentIndex, m_newPrimIndex; WorldEditorScene *m_scene; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_misc.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_misc.cpp index 1f77ee63d..5b5b9540d 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_misc.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_misc.cpp @@ -365,11 +365,25 @@ NLLIGO::IPrimitive *createPrimitive(const char *className, const char *primName, } break; case NLLIGO::CPrimitiveClass::Path: - primitive = new NLLIGO::CPrimPath; + { + NLLIGO::CPrimPath *path = new NLLIGO::CPrimPath; + primitive = path; + path->VPoints.push_back(NLLIGO::CPrimVector(initPos)); + NLMISC::CVector secondPos = NLMISC::CVector(initPos.x + deltaPos, initPos.y, 0.0); + path->VPoints.push_back(NLLIGO::CPrimVector(secondPos)); break; + } case NLLIGO::CPrimitiveClass::Zone: - primitive = new NLLIGO::CPrimZone; + { + NLLIGO::CPrimZone *zone = new NLLIGO::CPrimZone; + primitive = zone; + zone->VPoints.push_back(NLLIGO::CPrimVector(initPos)); + NLMISC::CVector secondPos = NLMISC::CVector(initPos.x + deltaPos, initPos.y, 0.0); + zone->VPoints.push_back(NLLIGO::CPrimVector(secondPos)); + secondPos.y = initPos.y + deltaPos; + zone->VPoints.push_back(NLLIGO::CPrimVector(secondPos)); break; + } case NLLIGO::CPrimitiveClass::Alias: primitive = new NLLIGO::CPrimAlias; break; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.cpp index 056a4f01e..9eb8e0717 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.cpp @@ -187,7 +187,7 @@ void WorldItemPoint::createCircle() if (m_radius != 0) { // Create circle - int segmentCount = 30; + int segmentCount = 20; QPointF circlePoint(m_radius, 0); m_circle << circlePoint; for (int i = 1; i < segmentCount + 1; ++i) @@ -241,9 +241,13 @@ void WorldItemPoint::paint(QPainter *painter, const QStyleOptionGraphicsItem *op painter->setPen(Qt::NoPen); // if (option->state & QStyle::State_Selected) if (isActived()) + { painter->setBrush(m_selectedBrush); + } else + { painter->setBrush(m_brush); + } // Draw point painter->drawRect(m_rect); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h index 1b934d77b..54811e271 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h @@ -129,7 +129,7 @@ private: void createCircle(); void updateBoundingRect(); - static const int SIZE_POINT = 3; + static const int SIZE_POINT = 2; QPen m_pen, m_selectedPen; QBrush m_brush, m_selectedBrush; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui index 1de6cbdc3..870081d47 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui @@ -6,7 +6,7 @@ 0 0 - 800 + 819 600 @@ -121,8 +121,9 @@ false - - + + + @@ -177,7 +178,7 @@ S/H Land
- + true @@ -185,10 +186,13 @@ false - S/H Primitives + S/H Zone primitives + + + S/H Zone Primitives - + true @@ -196,7 +200,7 @@ false - S/H Layers + S/H Path primitives @@ -343,6 +347,20 @@ Project settings + + + true + + + false + + + S/H Points primitives + + + S/H Points primitives + + From 782425f9dfb80fc26f56a6b201de92ca8a561d39 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Tue, 16 Aug 2011 13:52:06 +0300 Subject: [PATCH 59/89] Changed: #1302 Added save/saveAs action for primitive item. --HG-- branch : gsoc2011-worldeditorqt --- .../plugins/world_editor/primitive_item.cpp | 12 ++++ .../src/plugins/world_editor/primitive_item.h | 4 ++ .../plugins/world_editor/primitives_model.cpp | 10 ++- .../plugins/world_editor/primitives_view.cpp | 63 +++++++++++++++++-- .../plugins/world_editor/primitives_view.h | 2 + .../world_editor/world_editor_actions.cpp | 4 +- .../world_editor/world_editor_constants.h | 2 + 7 files changed, 89 insertions(+), 8 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.cpp index e948f8b0f..e867f1368 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.cpp @@ -235,6 +235,7 @@ Node::NodeType PrimitiveNode::type() const RootPrimitiveNode::RootPrimitiveNode(const QString &name, NLLIGO::CPrimitives *primitives) : PrimitiveNode(primitives->RootNode), + m_fileName(name), m_primitives(primitives) { setData(Qt::DisplayRole, name); @@ -249,6 +250,17 @@ NLLIGO::CPrimitives *RootPrimitiveNode::primitives() const return m_primitives; } +void RootPrimitiveNode::setFileName(const QString &fileName) +{ + setData(Qt::DisplayRole, fileName); + m_fileName = fileName; +} + +QString RootPrimitiveNode::fileName() const +{ + return m_fileName; +} + Node::NodeType RootPrimitiveNode::type() const { return RootPrimitiveNodeType; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h index 1b2a89d4c..300973c55 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h @@ -167,9 +167,13 @@ public: NLLIGO::CPrimitives *primitives() const; + void setFileName(const QString &fileName); + QString fileName() const; virtual NodeType type() const; private: + + QString m_fileName; NLLIGO::CPrimitives *m_primitives; }; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.cpp index f59cb8d67..9e689066a 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.cpp @@ -18,6 +18,7 @@ #include "primitive_item.h" #include "primitives_model.h" #include "world_editor_misc.h" +#include "world_editor_constants.h" // NeL includes #include @@ -218,6 +219,10 @@ Path PrimitivesTreeModel::createRootPrimitiveNode(const QString &fileName, NLLIG if (m_worldEditNode == 0) createWorldEditNode("NewWorldEdit"); + QString name = "NewPrimitive"; + if (!fileName.isEmpty()) + name = fileName; + // Get position int pos = m_worldEditNode->childCount(); @@ -225,10 +230,13 @@ Path PrimitivesTreeModel::createRootPrimitiveNode(const QString &fileName, NLLIG // Add root node in tree model beginInsertRows(parentIndex, pos, pos); - RootPrimitiveNode *newNode = new RootPrimitiveNode(fileName, primitives); + RootPrimitiveNode *newNode = new RootPrimitiveNode(name, primitives); m_worldEditNode->appendChildNode(newNode); endInsertRows(); + newNode->setData(Constants::PRIMITIVE_FILE_IS_CREATED, !fileName.isEmpty()); + newNode->setData(Constants::PRIMITIVE_IS_MODIFIED, false); + QModelIndex rootPrimIndex = index(pos, 0, parentIndex); // Scan childs items and add in the tree model diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.cpp index 896218a54..0a2851e65 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.cpp @@ -18,6 +18,7 @@ #include "primitives_view.h" #include "primitives_model.h" #include "world_editor_actions.h" +#include "world_editor_constants.h" #include "../core/core_constants.h" #include "../landscape_editor/landscape_editor_constants.h" @@ -27,9 +28,11 @@ #include #include #include +#include // Qt includes #include +#include #include #include @@ -49,12 +52,10 @@ PrimitivesView::PrimitivesView(QWidget *parent) 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)); @@ -83,6 +84,8 @@ PrimitivesView::PrimitivesView(QWidget *parent) connect(m_newPrimitiveAction, SIGNAL(triggered()), this, SLOT(createRootPrimitive())); connect(m_selectChildrenAction, SIGNAL(triggered()), this, SLOT(selectChildren())); connect(m_deleteAction, SIGNAL(triggered()), this, SLOT(deletePrimitives())); + connect(m_saveAction, SIGNAL(triggered()), this, SLOT(save())); + connect(m_saveAsAction, SIGNAL(triggered()), this, SLOT(saveAs())); #ifdef Q_OS_DARWIN setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); @@ -186,6 +189,54 @@ void PrimitivesView::selectChildren() selectChildren(parentIndex); } +void PrimitivesView::save() +{ + nlassert(m_primitivesTreeModel); + + QModelIndexList indexList = selectionModel()->selectedRows(); + QModelIndex index = indexList.first(); + + RootPrimitiveNode *node = static_cast(index.internalPointer()); + + if (node->data(Constants::PRIMITIVE_FILE_IS_CREATED).toBool()) + { + if (!NLLIGO::saveXmlPrimitiveFile(*node->primitives(), node->fileName().toStdString())) + QMessageBox::warning(this, "World Editor Qt", QString("Error writing output file: %1").arg(node->fileName())); + else + node->setData(Constants::PRIMITIVE_IS_MODIFIED, false); + } + else + saveAs(); +} + +void PrimitivesView::saveAs() +{ + nlassert(m_primitivesTreeModel); + + QString fileName = QFileDialog::getSaveFileName(this, + tr("Save NeL Ligo primitive file"), m_lastDir, + tr("NeL Ligo primitive file (*.primitive)")); + + setCursor(Qt::WaitCursor); + if (!fileName.isEmpty()) + { + QModelIndexList indexList = selectionModel()->selectedRows(); + QModelIndex index = indexList.first(); + + RootPrimitiveNode *node = static_cast(index.internalPointer()); + + if (!NLLIGO::saveXmlPrimitiveFile(*node->primitives(), fileName.toStdString())) + QMessageBox::warning(this, "World Editor Qt", QString("Error writing output file: %1").arg(fileName)); + else + { + node->setFileName(fileName); + node->setData(Constants::PRIMITIVE_FILE_IS_CREATED, true); + node->setData(Constants::PRIMITIVE_IS_MODIFIED, false); + } + } + setCursor(Qt::ArrowCursor); +} + void PrimitivesView::deletePrimitives() { nlassert(m_undoStack); @@ -267,8 +318,8 @@ void PrimitivesView::selectChildren(const QModelIndex &parent) void PrimitivesView::fillMenu_WorldEdit(QMenu *menu) { menu->addAction(m_unloadAction); - menu->addAction(m_saveAction); - menu->addAction(m_saveAsAction); + //menu->addAction(m_saveAction); + //menu->addAction(m_saveAsAction); menu->addSeparator(); menu->addAction(m_loadLandAction); menu->addAction(m_loadPrimitiveAction); @@ -279,7 +330,7 @@ void PrimitivesView::fillMenu_WorldEdit(QMenu *menu) void PrimitivesView::fillMenu_Landscape(QMenu *menu) { - menu->addAction(m_deleteAction); + menu->addAction(m_unloadAction); menu->addSeparator(); menu->addAction(m_showAction); menu->addAction(m_hideAction); @@ -289,7 +340,9 @@ void PrimitivesView::fillMenu_RootPrimitive(QMenu *menu, const QModelIndex &inde { menu->addAction(m_saveAction); menu->addAction(m_saveAsAction); + menu->addAction(m_unloadAction); fillMenu_Primitive(menu, index); + menu->removeAction(m_deleteAction); } void PrimitivesView::fillMenu_Primitive(QMenu *menu, const QModelIndex &index) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.h index eae9187ac..3fce65ae7 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.h @@ -67,6 +67,8 @@ private Q_SLOTS: void createRootPrimitive(); void selectChildren(); + void save(); + void saveAs(); void deletePrimitives(); void addNewPrimitiveByClass(int value); void generatePrimitives(int value); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp index f40e498a1..2eaa2a488 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp @@ -295,7 +295,7 @@ void CreateRootPrimitiveCommand::undo() void CreateRootPrimitiveCommand::redo() { NLLIGO::CPrimitives *newRootPrim = new NLLIGO::CPrimitives(); - m_rootPrimIndex = m_model->createRootPrimitiveNode(m_fileName, newRootPrim); + m_rootPrimIndex = m_model->createRootPrimitiveNode("", newRootPrim); } @@ -337,7 +337,7 @@ void LoadRootPrimitiveCommand::redo() // set the primitive context NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = primitives; - NLLIGO::loadXmlPrimitiveFile(*primitives, m_fileName.toStdString(), *NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig); + NLLIGO::loadXmlPrimitiveFile(*primitives, m_fileName.toStdString(), *Utils::ligoConfig()); // unset the context NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = NULL; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_constants.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_constants.h index e0bdc4705..9a7a834d6 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_constants.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_constants.h @@ -28,6 +28,8 @@ const int NODE_PERISTENT_INDEX = USER_TYPE + 1; const int WORLD_EDITOR_NODE = USER_TYPE + 2; const int GRAPHICS_DATA_QT4_2D = USER_TYPE + 3; const int GRAPHICS_DATA_NEL3D = USER_TYPE + 4; +const int PRIMITIVE_IS_MODIFIED = USER_TYPE + 5; +const int PRIMITIVE_FILE_IS_CREATED = USER_TYPE + 6; //settings const char *const WORLD_EDITOR_SECTION = "WorldEditor"; From 82f6999b4782408319d4182bd37c96aea5788e55 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Tue, 16 Aug 2011 19:34:21 +0300 Subject: [PATCH 60/89] Changed: #1302 Added save/saveAs action for primitive item. --HG-- branch : gsoc2011-worldeditorqt --- .../plugins/world_editor/primitives_view.cpp | 8 +- .../world_editor/world_editor_actions.cpp | 104 +++++++++++++++++- .../world_editor/world_editor_actions.h | 3 + .../world_editor/world_editor_scene_item.cpp | 14 +++ .../world_editor/world_editor_scene_item.h | 3 + 5 files changed, 127 insertions(+), 5 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.cpp index 0a2851e65..6620411ca 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.cpp @@ -197,7 +197,7 @@ void PrimitivesView::save() QModelIndex index = indexList.first(); RootPrimitiveNode *node = static_cast(index.internalPointer()); - + if (node->data(Constants::PRIMITIVE_FILE_IS_CREATED).toBool()) { if (!NLLIGO::saveXmlPrimitiveFile(*node->primitives(), node->fileName().toStdString())) @@ -214,8 +214,8 @@ void PrimitivesView::saveAs() nlassert(m_primitivesTreeModel); QString fileName = QFileDialog::getSaveFileName(this, - tr("Save NeL Ligo primitive file"), m_lastDir, - tr("NeL Ligo primitive file (*.primitive)")); + tr("Save NeL Ligo primitive file"), m_lastDir, + tr("NeL Ligo primitive file (*.primitive)")); setCursor(Qt::WaitCursor); if (!fileName.isEmpty()) @@ -224,7 +224,7 @@ void PrimitivesView::saveAs() QModelIndex index = indexList.first(); RootPrimitiveNode *node = static_cast(index.internalPointer()); - + if (!NLLIGO::saveXmlPrimitiveFile(*node->primitives(), fileName.toStdString())) QMessageBox::warning(this, "World Editor Qt", QString("Error writing output file: %1").arg(fileName)); else diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp index 2eaa2a488..2e538748c 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp @@ -121,7 +121,7 @@ void addNewGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *mode for (int i = 0; i < sizeVec; ++i) { - polygon << QPointF(vec->x, -vec->y + cellSize); + polygon << QPointF(vec->x, cellSize - vec->y); ++vec; } item = scene->addWorldItemZone(polygon); @@ -216,6 +216,49 @@ QList polygonsFromItems(const QList &items) return result; } +void updateGraphicsData(AbstractWorldItem *item) +{ + float cellSize = Utils::ligoConfig()->CellSize; + Node *node = qvariant_cast(item->data(Constants::WORLD_EDITOR_NODE)); + PrimitiveNode *primitiveNode = static_cast(node); + if (primitiveNode != 0) + { + NLLIGO::IPrimitive *primitive = primitiveNode->primitive(); + + std::vector vPoints; + QPolygonF polygon = item->polygon(); + polygon.translate(item->pos()); + + for (int i = 0; i < polygon.size(); ++i) + { + NLMISC::CVector vec(polygon.at(i).x(), cellSize - polygon.at(i).y(), 0.0); + vPoints.push_back(NLLIGO::CPrimVector(vec)); + } + + switch (primitiveNode->primitiveClass()->Type) + { + case NLLIGO::CPrimitiveClass::Point: + { + NLLIGO::CPrimPoint *point = static_cast(primitive); + point->Point = vPoints.front(); + break; + } + case NLLIGO::CPrimitiveClass::Path: + { + NLLIGO::CPrimPath *path = static_cast(primitive); + path->VPoints = vPoints; + break; + } + case NLLIGO::CPrimitiveClass::Zone: + { + NLLIGO::CPrimZone *zone = static_cast(primitive); + zone->VPoints = vPoints; + break; + } + } + } +} + CreateWorldCommand::CreateWorldCommand(const QString &fileName, PrimitivesTreeModel *model, QUndoCommand *parent) : QUndoCommand(parent), m_fileName(fileName), @@ -451,6 +494,7 @@ void MoveWorldItemsCommand::undo() Node *node = m_model->pathToNode(m_listPaths.at(i)); AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); item->moveBy(-m_offset.x(), -m_offset.y()); + updateGraphicsData(item); } m_scene->setEnabledEditPoints(pointsMode); } @@ -466,9 +510,20 @@ void MoveWorldItemsCommand::redo() Node *node = m_model->pathToNode(m_listPaths.at(i)); AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); item->moveBy(m_offset.x(), m_offset.y()); + updateGraphicsData(item); } m_scene->setEnabledEditPoints(pointsMode); } + else + { + for (int i = 0; i < m_listPaths.count(); ++i) + { + Node *node = m_model->pathToNode(m_listPaths.at(i)); + AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); + updateGraphicsData(item); + } + } + m_firstRun = false; } @@ -498,6 +553,7 @@ void RotateWorldItemsCommand::undo() Node *node = m_model->pathToNode(m_listPaths.at(i)); AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); item->rotateOn(m_pivot, -m_angle); + updateGraphicsData(item); } m_scene->setEnabledEditPoints(pointsMode); } @@ -513,9 +569,20 @@ void RotateWorldItemsCommand::redo() Node *node = m_model->pathToNode(m_listPaths.at(i)); AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); item->rotateOn(m_pivot, m_angle); + updateGraphicsData(item); } m_scene->setEnabledEditPoints(pointsMode); } + else + { + for (int i = 0; i < m_listPaths.count(); ++i) + { + Node *node = m_model->pathToNode(m_listPaths.at(i)); + AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); + updateGraphicsData(item); + } + } + m_firstRun = false; } @@ -546,6 +613,7 @@ void ScaleWorldItemsCommand::undo() Node *node = m_model->pathToNode(m_listPaths.at(i)); AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); item->scaleOn(m_pivot, m_invertFactor); + updateGraphicsData(item); } m_scene->setEnabledEditPoints(pointsMode); } @@ -561,9 +629,20 @@ void ScaleWorldItemsCommand::redo() Node *node = m_model->pathToNode(m_listPaths.at(i)); AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); item->scaleOn(m_pivot, m_factor); + updateGraphicsData(item); } m_scene->setEnabledEditPoints(pointsMode); } + else + { + for (int i = 0; i < m_listPaths.count(); ++i) + { + Node *node = m_model->pathToNode(m_listPaths.at(i)); + AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); + updateGraphicsData(item); + } + } + m_firstRun = false; } @@ -592,6 +671,7 @@ void TurnWorldItemsCommand::undo() Node *node = m_model->pathToNode(m_listPaths.at(i)); AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); item->turnOn(-m_angle); + updateGraphicsData(item); } m_scene->setEnabledEditPoints(pointsMode); } @@ -607,9 +687,19 @@ void TurnWorldItemsCommand::redo() Node *node = m_model->pathToNode(m_listPaths.at(i)); AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); item->turnOn(m_angle); + updateGraphicsData(item); } m_scene->setEnabledEditPoints(pointsMode); } + else + { + for (int i = 0; i < m_listPaths.count(); ++i) + { + Node *node = m_model->pathToNode(m_listPaths.at(i)); + AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); + updateGraphicsData(item); + } + } m_firstRun = false; } @@ -642,6 +732,7 @@ void ShapeWorldItemsCommand::undo() Node *node = m_model->pathToNode(m_listPaths.at(i)); AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); item->setPolygon(m_redoPolygons.at(i)); + updateGraphicsData(item); } m_scene->setEnabledEditPoints(pointsMode); @@ -659,9 +750,20 @@ void ShapeWorldItemsCommand::redo() Node *node = m_model->pathToNode(m_listPaths.at(i)); AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); item->setPolygon(m_undoPolygons.at(i)); + updateGraphicsData(item); } m_scene->setEnabledEditPoints(pointsMode); } + else + { + for (int i = 0; i < m_listPaths.count(); ++i) + { + Node *node = m_model->pathToNode(m_listPaths.at(i)); + AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); + updateGraphicsData(item); + } + } + m_firstRun = false; } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h index a8352e2e6..1c77a4ba5 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h @@ -35,6 +35,7 @@ class ZoneBuilderBase; namespace WorldEditor { class WorldEditorScene; +class AbstractWorldItem; // Auxiliary operations @@ -50,6 +51,8 @@ QList graphicsItemsToPaths(const QList &items, Primitives QList polygonsFromItems(const QList &items); +void updateGraphicsData(AbstractWorldItem *item); + /** @class CreateWorldCommand @brief diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.cpp index 9eb8e0717..28c933d39 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.cpp @@ -182,6 +182,17 @@ void WorldItemPoint::setColor(const QColor &color) m_brush.setColor(color); } +void WorldItemPoint::setPolygon(const QPolygonF &polygon) +{ +} + +QPolygonF WorldItemPoint::polygon() const +{ + QPolygonF polygon; + polygon << QPointF(0, 0); + return polygon; +} + void WorldItemPoint::createCircle() { if (m_radius != 0) @@ -339,6 +350,7 @@ void WorldItemPath::moveSubPoint(WorldItemSubPoint *subPoint) m_listLines.at(i).itemPoint->setPos((m_listLines.at(i).lineItem.first->pos() + m_listLines.at(i).lineItem.second->pos()) / 2); m_polygon = polygon; + setShapeChanged(true); update(); } @@ -381,6 +393,7 @@ void WorldItemPath::addSubPoint(WorldItemSubPoint *subPoint) break; } } + setShapeChanged(true); } bool WorldItemPath::removeSubPoint(WorldItemSubPoint *subPoint) @@ -427,6 +440,7 @@ bool WorldItemPath::removeSubPoint(WorldItemSubPoint *subPoint) subPoint->setPos((newLineItem.lineItem.first->pos() + newLineItem.lineItem.second->pos()) / 2); m_listLines.push_back(newLineItem); subPoint->setFlag(ItemSendsScenePositionChanges, false); + setShapeChanged(true); return true; } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h index 54811e271..b42138833 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h @@ -121,6 +121,9 @@ public: virtual void setColor(const QColor &color); virtual void setEnabledSubPoints(bool enabled) {} + virtual void setPolygon(const QPolygonF &polygon); + virtual QPolygonF polygon() const; + virtual QRectF boundingRect() const; virtual QPainterPath shape() const; virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); From 6f6477eb1c3465b9857de8aca3fe84ae09977027 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Tue, 16 Aug 2011 21:18:10 +0300 Subject: [PATCH 61/89] Changed: #1302 When selecting graphics items in scene will be selected the appropriate primitives in the primitives dialog. --HG-- branch : gsoc2011-worldeditorqt --- .../plugins/world_editor/primitives_model.cpp | 2 +- .../world_editor/world_editor_actions.cpp | 8 +++++ .../world_editor/world_editor_actions.h | 4 +++ .../world_editor/world_editor_scene.cpp | 5 +++ .../plugins/world_editor/world_editor_scene.h | 2 +- .../world_editor/world_editor_window.cpp | 33 +++++++++++++++++++ .../world_editor/world_editor_window.h | 1 + 7 files changed, 53 insertions(+), 2 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.cpp index 9e689066a..690e7db08 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.cpp @@ -155,7 +155,7 @@ Path PrimitivesTreeModel::pathFromNode(Node *node) Path path; while(iter != 0) { - path.prepend(PathItem(iter->row(), 1)); + path.prepend(PathItem(iter->row(), 0)); iter = iter->parent(); } return path; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp index 2e538748c..eb1921596 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp @@ -167,6 +167,11 @@ void addNewGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *mode QVariant graphicsData; graphicsData.setValue(item); node->setData(Constants::GRAPHICS_DATA_QT4_2D, graphicsData); + + QVariant persistenVariant; + QPersistentModelIndex *persistentIndex = new QPersistentModelIndex(primIndex); + persistenVariant.setValue(persistentIndex); + item->setData(Constants::NODE_PERISTENT_INDEX, persistenVariant); } int count = model->rowCount(primIndex); @@ -185,6 +190,8 @@ void removeGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *mode QGraphicsItem *item = getGraphicsItem(node); if (item != 0) scene->removeWorldItem(item); + + delete qvariant_cast(item->data(Constants::NODE_PERISTENT_INDEX)); } int count = model->rowCount(primIndex); @@ -358,6 +365,7 @@ LoadRootPrimitiveCommand::~LoadRootPrimitiveCommand() void LoadRootPrimitiveCommand::undo() { + // Disable edit points mode m_scene->setEnabledEditPoints(false); QModelIndex index = m_model->pathToIndex(m_rootPrimIndex); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h index 1c77a4ba5..8aae8b8dd 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h @@ -26,6 +26,7 @@ #include #include #include +#include namespace LandscapeEditor { @@ -283,4 +284,7 @@ private: } /* namespace WorldEditor */ +// Enable the use of QVariant with this class. +Q_DECLARE_METATYPE(QPersistentModelIndex *) + #endif // WORLD_EDITOR_ACTIONS_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp index 749392631..356f6589a 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp @@ -459,6 +459,9 @@ void WorldEditorScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent) m_selectedItems.push_back(item); } + + Q_EMIT updateSelectedItems(m_selectedItems); + updateSelectedWorldItems(true); m_selectionArea = QRectF(); update(); @@ -556,6 +559,8 @@ void WorldEditorScene::updatePickSelection(const QPointF &point) m_selectedItems.push_back(worldItemsItems.at(m_lastPickedPrimitive)); updateSelectedWorldItems(true); } + + Q_EMIT updateSelectedItems(m_selectedItems); } void WorldEditorScene::updatePickSelectionPoints(const QPointF &point) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h index adf491889..c9da223a7 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h @@ -68,7 +68,7 @@ public: bool isEnabledEditPoints() const; Q_SIGNALS: - void selectionUpdated(const QList &selected, const QList &deselected); + void updateSelectedItems(const QList &selected); public Q_SLOTS: void setEnabledEditPoints(bool enabled); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp index 009ede2e1..97d99f82c 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp @@ -39,6 +39,7 @@ #include #include #include +#include namespace WorldEditor { @@ -108,6 +109,9 @@ WorldEditorWindow::WorldEditorWindow(QWidget *parent) connect(m_ui.treePrimitivesView->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this, SLOT(updateSelection(QItemSelection, QItemSelection))); + connect(m_worldEditorScene, SIGNAL(updateSelectedItems(QList)), + this, SLOT(selectedItemsInScene(QList))); + m_statusBarTimer = new QTimer(this); connect(m_statusBarTimer, SIGNAL(timeout()), this, SLOT(updateStatusBar())); @@ -295,6 +299,35 @@ void WorldEditorWindow::updateSelection(const QItemSelection &selected, const QI m_worldEditorScene->updateSelection(itemSelected, itemDeselected); } +void WorldEditorWindow::selectedItemsInScene(const QList &selected) +{ + QItemSelectionModel *selectionModel = m_ui.treePrimitivesView->selectionModel(); + disconnect(m_ui.treePrimitivesView->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), + this, SLOT(updateSelection(QItemSelection, QItemSelection))); + + selectionModel->clear(); + QItemSelection itemSelection; + Q_FOREACH(QGraphicsItem *item, selected) + { + QPersistentModelIndex *index = qvariant_cast(item->data(Constants::NODE_PERISTENT_INDEX)); + if (index->isValid()) + { + QModelIndex modelIndex = index->operator const QModelIndex &(); + QItemSelection mergeItemSelection(modelIndex, modelIndex); + itemSelection.merge(mergeItemSelection, QItemSelectionModel::Select); + } + QApplication::processEvents(); + } + + selectionModel->select(itemSelection, QItemSelectionModel::Select); + + // TODO: update property editor + // ... + + connect(m_ui.treePrimitivesView->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), + this, SLOT(updateSelection(QItemSelection, QItemSelection))); +} + void WorldEditorWindow::showEvent(QShowEvent *showEvent) { QMainWindow::showEvent(showEvent); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h index 5844489f6..d6e3dd593 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h @@ -61,6 +61,7 @@ private Q_SLOTS: void updateStatusBar(); void updateSelection(const QItemSelection &selected, const QItemSelection &deselected); + void selectedItemsInScene(const QList &selected); protected: virtual void showEvent(QShowEvent *showEvent); From 0918a42060afd91c69f4ab8b8f2c0259d552d1ca Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Tue, 16 Aug 2011 22:30:45 +0300 Subject: [PATCH 62/89] Fixed: #1302 Fixed crash program(LoadRootPrimitiveCommand and AddPrimitiveByClassCommand do not work with selection model, and edit points mode does not work with mouse panning). --HG-- branch : gsoc2011-worldeditorqt --- .../plugins/world_editor/primitives_view.cpp | 4 ++-- .../world_editor/world_editor_actions.cpp | 23 ++++++++++++------- .../world_editor/world_editor_actions.h | 8 +++++-- .../world_editor/world_editor_scene.cpp | 3 +++ .../world_editor/world_editor_window.cpp | 5 ++-- 5 files changed, 29 insertions(+), 14 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.cpp index 6620411ca..ca329b25b 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.cpp @@ -135,7 +135,7 @@ void PrimitivesView::loadRootPrimitive() Q_FOREACH(QString fileName, fileNames) { m_lastDir = QFileInfo(fileName).absolutePath(); - m_undoStack->push(new LoadRootPrimitiveCommand(fileName, m_worldEditorScene, m_primitivesTreeModel)); + m_undoStack->push(new LoadRootPrimitiveCommand(fileName, m_worldEditorScene, m_primitivesTreeModel, this)); } if (fileNames.count() > 1) @@ -258,7 +258,7 @@ void PrimitivesView::addNewPrimitiveByClass(int value) QString className = node->primitiveClass()->DynamicChildren[value].ClassName.c_str(); m_undoStack->push(new AddPrimitiveByClassCommand(className, m_primitivesTreeModel->pathFromIndex(indexList.first()), - m_worldEditorScene, m_primitivesTreeModel)); + m_worldEditorScene, m_primitivesTreeModel, this)); } void PrimitivesView::generatePrimitives(int value) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp index eb1921596..9a70cebe6 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp @@ -189,9 +189,10 @@ void removeGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *mode { QGraphicsItem *item = getGraphicsItem(node); if (item != 0) + { + delete qvariant_cast(item->data(Constants::NODE_PERISTENT_INDEX)); scene->removeWorldItem(item); - - delete qvariant_cast(item->data(Constants::NODE_PERISTENT_INDEX)); + } } int count = model->rowCount(primIndex); @@ -350,11 +351,12 @@ void CreateRootPrimitiveCommand::redo() LoadRootPrimitiveCommand::LoadRootPrimitiveCommand(const QString &fileName, WorldEditorScene *scene, - PrimitivesTreeModel *model, QUndoCommand *parent) + PrimitivesTreeModel *model, QTreeView *view, QUndoCommand *parent) : QUndoCommand(parent), m_fileName(fileName), m_scene(scene), - m_model(model) + m_model(model), + m_view(view) { setText("Load primitive file"); } @@ -368,6 +370,8 @@ void LoadRootPrimitiveCommand::undo() // Disable edit points mode m_scene->setEnabledEditPoints(false); + m_view->selectionModel()->clearSelection(); + QModelIndex index = m_model->pathToIndex(m_rootPrimIndex); removeGraphicsItems(index, m_model, m_scene); @@ -409,19 +413,20 @@ void LoadRootPrimitiveCommand::redo() } AddPrimitiveByClassCommand::AddPrimitiveByClassCommand(const QString &className, const Path &parentIndex, - WorldEditorScene *scene, PrimitivesTreeModel *model, QUndoCommand *parent) + WorldEditorScene *scene, PrimitivesTreeModel *model, QTreeView *view, QUndoCommand *parent) : QUndoCommand(parent), m_className(className), m_parentIndex(parentIndex), m_scene(scene), - m_model(model) + m_model(model), + m_view(view) { setText(QString("Add %1").arg(m_className)); - QGraphicsView *view = m_scene->views().first(); + QGraphicsView *graphicsView = m_scene->views().first(); // TODO: returns incorrect position when zoom in - QRectF visibleArea = view->mapToScene(view->rect()).boundingRect(); + QRectF visibleArea = graphicsView->mapToScene(view->rect()).boundingRect(); m_delta = visibleArea.height() / 10.0; m_initPos = visibleArea.center(); } @@ -434,6 +439,8 @@ void AddPrimitiveByClassCommand::undo() { m_scene->setEnabledEditPoints(false); + m_view->selectionModel()->clearSelection(); + QModelIndex index = m_model->pathToIndex(m_newPrimIndex); PrimitiveNode *node = static_cast(index.internalPointer()); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h index 8aae8b8dd..ad66d0e3d 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h @@ -25,6 +25,7 @@ // Qt includes #include #include +#include #include #include @@ -121,7 +122,8 @@ class LoadRootPrimitiveCommand: public QUndoCommand { public: LoadRootPrimitiveCommand(const QString &fileName, WorldEditorScene *scene, - PrimitivesTreeModel *model, QUndoCommand *parent = 0); + PrimitivesTreeModel *model, QTreeView *view, + QUndoCommand *parent = 0); virtual ~LoadRootPrimitiveCommand(); virtual void undo(); @@ -132,6 +134,7 @@ private: const QString m_fileName; WorldEditorScene *const m_scene; PrimitivesTreeModel *const m_model; + QTreeView *m_view; }; /** @@ -144,7 +147,7 @@ class AddPrimitiveByClassCommand: public QUndoCommand public: AddPrimitiveByClassCommand(const QString &className, const Path &parentIndex, WorldEditorScene *scene, PrimitivesTreeModel *model, - QUndoCommand *parent = 0); + QTreeView *view, QUndoCommand *parent = 0); virtual ~AddPrimitiveByClassCommand(); virtual void undo(); @@ -157,6 +160,7 @@ private: Path m_parentIndex, m_newPrimIndex; WorldEditorScene *m_scene; PrimitivesTreeModel *m_model; + QTreeView *m_view; }; /** diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp index 356f6589a..967f6651d 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp @@ -369,6 +369,9 @@ void WorldEditorScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) void WorldEditorScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent) { + if (mouseEvent->button() == Qt::MidButton) + return; + if (m_pointsMode) { if (mouseEvent->button() == Qt::LeftButton) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp index 97d99f82c..2df27d7c7 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp @@ -193,7 +193,8 @@ void WorldEditorWindow::loadWorldEditFile(const QString &fileName) 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_worldEditorScene, m_primitivesModel)); + m_undoStack->push(new LoadRootPrimitiveCommand(QString(worldEditList[i].second.c_str()), + m_worldEditorScene, m_primitivesModel, m_ui.treePrimitivesView)); break; }; } @@ -383,7 +384,7 @@ void WorldEditorWindow::readSettings() restoreGeometry(settings->value(Constants::WORLD_WINDOW_GEOMETRY).toByteArray()); // Use OpenGL graphics system instead raster graphics system - if (settings->value(Constants::WORLD_EDITOR_USE_OPENGL, true).toBool()) + if (settings->value(Constants::WORLD_EDITOR_USE_OPENGL, false).toBool()) { m_oglWidget = new QGLWidget(QGLFormat(QGL::DoubleBuffer)); m_ui.graphicsView->setViewport(m_oglWidget); From adbcdcd9f0c0e9b06348b33dd1a6b8046c9bfae6 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Wed, 17 Aug 2011 02:49:32 +0300 Subject: [PATCH 63/89] Changed: #1302 Clean up code for undo commands. --HG-- branch : gsoc2011-worldeditorqt --- .../world_editor/world_editor_actions.cpp | 349 ++++++------------ .../world_editor/world_editor_actions.h | 91 +++-- 2 files changed, 166 insertions(+), 274 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp index 9a70cebe6..b0a201980 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp @@ -202,17 +202,6 @@ void removeGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *mode } } -QList graphicsItemsToPaths(const QList &items, PrimitivesTreeModel *model) -{ - QList result; - Q_FOREACH(QGraphicsItem *item, items) - { - Node *node = qvariant_cast(item->data(Constants::WORLD_EDITOR_NODE)); - result.push_back(model->pathFromNode(node)); - } - return result; -} - QList polygonsFromItems(const QList &items) { QList result; @@ -224,49 +213,6 @@ QList polygonsFromItems(const QList &items) return result; } -void updateGraphicsData(AbstractWorldItem *item) -{ - float cellSize = Utils::ligoConfig()->CellSize; - Node *node = qvariant_cast(item->data(Constants::WORLD_EDITOR_NODE)); - PrimitiveNode *primitiveNode = static_cast(node); - if (primitiveNode != 0) - { - NLLIGO::IPrimitive *primitive = primitiveNode->primitive(); - - std::vector vPoints; - QPolygonF polygon = item->polygon(); - polygon.translate(item->pos()); - - for (int i = 0; i < polygon.size(); ++i) - { - NLMISC::CVector vec(polygon.at(i).x(), cellSize - polygon.at(i).y(), 0.0); - vPoints.push_back(NLLIGO::CPrimVector(vec)); - } - - switch (primitiveNode->primitiveClass()->Type) - { - case NLLIGO::CPrimitiveClass::Point: - { - NLLIGO::CPrimPoint *point = static_cast(primitive); - point->Point = vPoints.front(); - break; - } - case NLLIGO::CPrimitiveClass::Path: - { - NLLIGO::CPrimPath *path = static_cast(primitive); - path->VPoints = vPoints; - break; - } - case NLLIGO::CPrimitiveClass::Zone: - { - NLLIGO::CPrimZone *zone = static_cast(primitive); - zone->VPoints = vPoints; - break; - } - } - } -} - CreateWorldCommand::CreateWorldCommand(const QString &fileName, PrimitivesTreeModel *model, QUndoCommand *parent) : QUndoCommand(parent), m_fileName(fileName), @@ -484,23 +430,23 @@ void AddPrimitiveByClassCommand::redo() addNewGraphicsItems(m_model->pathToIndex(m_newPrimIndex), m_model, m_scene); } -MoveWorldItemsCommand::MoveWorldItemsCommand(const QList &items, const QPointF &offset, - WorldEditorScene *scene, PrimitivesTreeModel *model, QUndoCommand *parent) +AbstractWorldItemCommand::AbstractWorldItemCommand(const QList &items, + WorldEditorScene *scene, + PrimitivesTreeModel *model, + QUndoCommand *parent) : QUndoCommand(parent), m_listPaths(graphicsItemsToPaths(items, model)), - m_offset(offset), m_model(model), m_scene(scene), m_firstRun(true) { - setText("Move item(s)"); } -MoveWorldItemsCommand::~MoveWorldItemsCommand() +AbstractWorldItemCommand::~AbstractWorldItemCommand() { } -void MoveWorldItemsCommand::undo() +void AbstractWorldItemCommand::undo() { bool pointsMode = m_scene->isEnabledEditPoints(); m_scene->setEnabledEditPoints(false); @@ -508,13 +454,13 @@ void MoveWorldItemsCommand::undo() { Node *node = m_model->pathToNode(m_listPaths.at(i)); AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); - item->moveBy(-m_offset.x(), -m_offset.y()); - updateGraphicsData(item); + undoChangeItem(i, item); + updatePrimitiveData(item); } m_scene->setEnabledEditPoints(pointsMode); } -void MoveWorldItemsCommand::redo() +void AbstractWorldItemCommand::redo() { if (!m_firstRun) { @@ -524,8 +470,8 @@ void MoveWorldItemsCommand::redo() { Node *node = m_model->pathToNode(m_listPaths.at(i)); AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); - item->moveBy(m_offset.x(), m_offset.y()); - updateGraphicsData(item); + redoChangeItem(i, item); + updatePrimitiveData(item); } m_scene->setEnabledEditPoints(pointsMode); } @@ -535,22 +481,94 @@ void MoveWorldItemsCommand::redo() { Node *node = m_model->pathToNode(m_listPaths.at(i)); AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); - updateGraphicsData(item); + updatePrimitiveData(item); } } m_firstRun = false; } +void AbstractWorldItemCommand::updatePrimitiveData(AbstractWorldItem *item) +{ + float cellSize = Utils::ligoConfig()->CellSize; + Node *node = qvariant_cast(item->data(Constants::WORLD_EDITOR_NODE)); + PrimitiveNode *primitiveNode = static_cast(node); + if (primitiveNode != 0) + { + NLLIGO::IPrimitive *primitive = primitiveNode->primitive(); + + std::vector vPoints; + QPolygonF polygon = item->polygon(); + polygon.translate(item->pos()); + + for (int i = 0; i < polygon.size(); ++i) + { + NLMISC::CVector vec(polygon.at(i).x(), cellSize - polygon.at(i).y(), 0.0); + vPoints.push_back(NLLIGO::CPrimVector(vec)); + } + + switch (primitiveNode->primitiveClass()->Type) + { + case NLLIGO::CPrimitiveClass::Point: + { + NLLIGO::CPrimPoint *point = static_cast(primitive); + point->Point = vPoints.front(); + break; + } + case NLLIGO::CPrimitiveClass::Path: + { + NLLIGO::CPrimPath *path = static_cast(primitive); + path->VPoints = vPoints; + break; + } + case NLLIGO::CPrimitiveClass::Zone: + { + NLLIGO::CPrimZone *zone = static_cast(primitive); + zone->VPoints = vPoints; + break; + } + } + } +} + +QList AbstractWorldItemCommand::graphicsItemsToPaths(const QList &items, PrimitivesTreeModel *model) +{ + QList result; + Q_FOREACH(QGraphicsItem *item, items) + { + Node *node = qvariant_cast(item->data(Constants::WORLD_EDITOR_NODE)); + result.push_back(model->pathFromNode(node)); + } + return result; +} + +MoveWorldItemsCommand::MoveWorldItemsCommand(const QList &items, const QPointF &offset, + WorldEditorScene *scene, PrimitivesTreeModel *model, QUndoCommand *parent) + : AbstractWorldItemCommand(items, scene, model, parent), + m_offset(offset) +{ + setText("Move item(s)"); +} + +MoveWorldItemsCommand::~MoveWorldItemsCommand() +{ +} + +void MoveWorldItemsCommand::undoChangeItem(int i, AbstractWorldItem *item) +{ + item->moveBy(-m_offset.x(), -m_offset.y()); +} + +void MoveWorldItemsCommand::redoChangeItem(int i, AbstractWorldItem *item) +{ + item->moveBy(m_offset.x(), m_offset.y()); +} + RotateWorldItemsCommand::RotateWorldItemsCommand(const QList &items, const qreal angle, const QPointF &pivot, WorldEditorScene *scene, PrimitivesTreeModel *model, QUndoCommand *parent) - : QUndoCommand(parent), - m_listPaths(graphicsItemsToPaths(items, model)), + : AbstractWorldItemCommand(items, scene, model, parent), m_angle(angle), - m_pivot(pivot), - m_model(model), - m_scene(scene), - m_firstRun(true) + m_pivot(pivot) { setText("Rotate item(s)"); } @@ -559,57 +577,21 @@ RotateWorldItemsCommand::~RotateWorldItemsCommand() { } -void RotateWorldItemsCommand::undo() +void RotateWorldItemsCommand::undoChangeItem(int i, AbstractWorldItem *item) { - bool pointsMode = m_scene->isEnabledEditPoints(); - m_scene->setEnabledEditPoints(false); - for (int i = 0; i < m_listPaths.count(); ++i) - { - Node *node = m_model->pathToNode(m_listPaths.at(i)); - AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); - item->rotateOn(m_pivot, -m_angle); - updateGraphicsData(item); - } - m_scene->setEnabledEditPoints(pointsMode); + item->rotateOn(m_pivot, -m_angle); } -void RotateWorldItemsCommand::redo() +void RotateWorldItemsCommand::redoChangeItem(int i, AbstractWorldItem *item) { - if (!m_firstRun) - { - bool pointsMode = m_scene->isEnabledEditPoints(); - m_scene->setEnabledEditPoints(false); - for (int i = 0; i < m_listPaths.count(); ++i) - { - Node *node = m_model->pathToNode(m_listPaths.at(i)); - AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); - item->rotateOn(m_pivot, m_angle); - updateGraphicsData(item); - } - m_scene->setEnabledEditPoints(pointsMode); - } - else - { - for (int i = 0; i < m_listPaths.count(); ++i) - { - Node *node = m_model->pathToNode(m_listPaths.at(i)); - AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); - updateGraphicsData(item); - } - } - - m_firstRun = false; + item->rotateOn(m_pivot, m_angle); } ScaleWorldItemsCommand::ScaleWorldItemsCommand(const QList &items, const QPointF &factor, const QPointF &pivot, WorldEditorScene *scene, PrimitivesTreeModel *model, QUndoCommand *parent) - : QUndoCommand(parent), - m_listPaths(graphicsItemsToPaths(items, model)), + : AbstractWorldItemCommand(items, scene, model, parent), m_factor(factor), - m_pivot(pivot), - m_model(model), - m_scene(scene), - m_firstRun(true) + m_pivot(pivot) { setText("Scale item(s)"); } @@ -618,57 +600,21 @@ ScaleWorldItemsCommand::~ScaleWorldItemsCommand() { } -void ScaleWorldItemsCommand::undo() +void ScaleWorldItemsCommand::undoChangeItem(int i, AbstractWorldItem *item) { - bool pointsMode = m_scene->isEnabledEditPoints(); - m_scene->setEnabledEditPoints(false); QPointF m_invertFactor(1 / m_factor.x(), 1 / m_factor.y()); - for (int i = 0; i < m_listPaths.count(); ++i) - { - Node *node = m_model->pathToNode(m_listPaths.at(i)); - AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); - item->scaleOn(m_pivot, m_invertFactor); - updateGraphicsData(item); - } - m_scene->setEnabledEditPoints(pointsMode); + item->scaleOn(m_pivot, m_invertFactor); } -void ScaleWorldItemsCommand::redo() +void ScaleWorldItemsCommand::redoChangeItem(int i, AbstractWorldItem *item) { - if (!m_firstRun) - { - bool pointsMode = m_scene->isEnabledEditPoints(); - m_scene->setEnabledEditPoints(false); - for (int i = 0; i < m_listPaths.count(); ++i) - { - Node *node = m_model->pathToNode(m_listPaths.at(i)); - AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); - item->scaleOn(m_pivot, m_factor); - updateGraphicsData(item); - } - m_scene->setEnabledEditPoints(pointsMode); - } - else - { - for (int i = 0; i < m_listPaths.count(); ++i) - { - Node *node = m_model->pathToNode(m_listPaths.at(i)); - AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); - updateGraphicsData(item); - } - } - - m_firstRun = false; + item->scaleOn(m_pivot, m_factor); } TurnWorldItemsCommand::TurnWorldItemsCommand(const QList &items, const qreal angle, WorldEditorScene *scene, PrimitivesTreeModel *model, QUndoCommand *parent) - : QUndoCommand(parent), - m_listPaths(graphicsItemsToPaths(items, model)), - m_angle(angle), - m_model(model), - m_scene(scene), - m_firstRun(true) + : AbstractWorldItemCommand(items, scene, model, parent), + m_angle(angle) { setText("Turn item(s)"); } @@ -677,58 +623,22 @@ TurnWorldItemsCommand::~TurnWorldItemsCommand() { } -void TurnWorldItemsCommand::undo() +void TurnWorldItemsCommand::undoChangeItem(int i, AbstractWorldItem *item) { - bool pointsMode = m_scene->isEnabledEditPoints(); - m_scene->setEnabledEditPoints(false); - for (int i = 0; i < m_listPaths.count(); ++i) - { - Node *node = m_model->pathToNode(m_listPaths.at(i)); - AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); - item->turnOn(-m_angle); - updateGraphicsData(item); - } - m_scene->setEnabledEditPoints(pointsMode); + item->turnOn(-m_angle); } -void TurnWorldItemsCommand::redo() +void TurnWorldItemsCommand::redoChangeItem(int i, AbstractWorldItem *item) { - if (!m_firstRun) - { - bool pointsMode = m_scene->isEnabledEditPoints(); - m_scene->setEnabledEditPoints(false); - for (int i = 0; i < m_listPaths.count(); ++i) - { - Node *node = m_model->pathToNode(m_listPaths.at(i)); - AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); - item->turnOn(m_angle); - updateGraphicsData(item); - } - m_scene->setEnabledEditPoints(pointsMode); - } - else - { - for (int i = 0; i < m_listPaths.count(); ++i) - { - Node *node = m_model->pathToNode(m_listPaths.at(i)); - AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); - updateGraphicsData(item); - } - } - - m_firstRun = false; + item->turnOn(m_angle); } ShapeWorldItemsCommand::ShapeWorldItemsCommand(const QList &items, const QList &polygons, WorldEditorScene *scene, PrimitivesTreeModel *model, QUndoCommand *parent) - : QUndoCommand(parent), - m_listPaths(graphicsItemsToPaths(items, model)), + : AbstractWorldItemCommand(items, scene, model, parent), m_redoPolygons(polygons), - m_undoPolygons(polygonsFromItems(items)), - m_model(model), - m_scene(scene), - m_firstRun(true) + m_undoPolygons(polygonsFromItems(items)) { setText("Change shape"); } @@ -737,49 +647,14 @@ ShapeWorldItemsCommand::~ShapeWorldItemsCommand() { } -void ShapeWorldItemsCommand::undo() +void ShapeWorldItemsCommand::undoChangeItem(int i, AbstractWorldItem *item) { - bool pointsMode = m_scene->isEnabledEditPoints(); - m_scene->setEnabledEditPoints(false); - - for (int i = 0; i < m_listPaths.count(); ++i) - { - Node *node = m_model->pathToNode(m_listPaths.at(i)); - AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); - item->setPolygon(m_redoPolygons.at(i)); - updateGraphicsData(item); - } - - m_scene->setEnabledEditPoints(pointsMode); + item->setPolygon(m_redoPolygons.at(i)); } -void ShapeWorldItemsCommand::redo() +void ShapeWorldItemsCommand::redoChangeItem(int i, AbstractWorldItem *item) { - if (!m_firstRun) - { - bool pointsMode = m_scene->isEnabledEditPoints(); - m_scene->setEnabledEditPoints(false); - - for (int i = 0; i < m_listPaths.count(); ++i) - { - Node *node = m_model->pathToNode(m_listPaths.at(i)); - AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); - item->setPolygon(m_undoPolygons.at(i)); - updateGraphicsData(item); - } - m_scene->setEnabledEditPoints(pointsMode); - } - else - { - for (int i = 0; i < m_listPaths.count(); ++i) - { - Node *node = m_model->pathToNode(m_listPaths.at(i)); - AbstractWorldItem *item = qvariant_cast(node->data(Constants::GRAPHICS_DATA_QT4_2D)); - updateGraphicsData(item); - } - } - - m_firstRun = false; + item->setPolygon(m_undoPolygons.at(i)); } } /* namespace WorldEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h index ad66d0e3d..17f19fbca 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h @@ -49,11 +49,9 @@ void addNewGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *mode // Recursive scan primitives model for delete Graphics Items void removeGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *model, WorldEditorScene *scene); -QList graphicsItemsToPaths(const QList &items, PrimitivesTreeModel *model); QList polygonsFromItems(const QList &items); -void updateGraphicsData(AbstractWorldItem *item); /** @class CreateWorldCommand @@ -164,35 +162,62 @@ private: }; /** -@class MoveWorldItemsCommand +@class AbstractWorldItemCommand @brief @details */ -class MoveWorldItemsCommand: public QUndoCommand +class AbstractWorldItemCommand: public QUndoCommand { public: - MoveWorldItemsCommand(const QList &items, const QPointF &offset, - WorldEditorScene *scene, PrimitivesTreeModel *model, - QUndoCommand *parent = 0); - virtual ~MoveWorldItemsCommand(); + AbstractWorldItemCommand(const QList &items, WorldEditorScene *scene, + PrimitivesTreeModel *model, QUndoCommand *parent = 0); + virtual ~AbstractWorldItemCommand(); virtual void undo(); virtual void redo(); + +protected: + virtual void undoChangeItem(int i, AbstractWorldItem *item) = 0; + virtual void redoChangeItem(int i, AbstractWorldItem *item) = 0; + void updatePrimitiveData(AbstractWorldItem *item); + private: + QList graphicsItemsToPaths(const QList &items, PrimitivesTreeModel *model); const QList m_listPaths; - const QPointF m_offset; PrimitivesTreeModel *const m_model; WorldEditorScene *m_scene; bool m_firstRun; }; +/** +@class MoveWorldItemsCommand +@brief +@details +*/ +class MoveWorldItemsCommand: public AbstractWorldItemCommand +{ +public: + MoveWorldItemsCommand(const QList &items, const QPointF &offset, + WorldEditorScene *scene, PrimitivesTreeModel *model, + QUndoCommand *parent = 0); + virtual ~MoveWorldItemsCommand(); + +protected: + virtual void undoChangeItem(int i, AbstractWorldItem *item); + virtual void redoChangeItem(int i, AbstractWorldItem *item); + +private: + + const QPointF m_offset; +}; + /** @class RotateWorldItemsCommand @brief @details */ -class RotateWorldItemsCommand: public QUndoCommand +class RotateWorldItemsCommand: public AbstractWorldItemCommand { public: RotateWorldItemsCommand(const QList &items, const qreal angle, @@ -200,16 +225,14 @@ public: PrimitivesTreeModel *model, QUndoCommand *parent = 0); virtual ~RotateWorldItemsCommand(); - virtual void undo(); - virtual void redo(); +protected: + virtual void undoChangeItem(int i, AbstractWorldItem *item); + virtual void redoChangeItem(int i, AbstractWorldItem *item); + private: - const QList m_listPaths; const qreal m_angle; const QPointF m_pivot; - PrimitivesTreeModel *const m_model; - WorldEditorScene *m_scene; - bool m_firstRun; }; /** @@ -217,7 +240,7 @@ private: @brief @details */ -class ScaleWorldItemsCommand: public QUndoCommand +class ScaleWorldItemsCommand: public AbstractWorldItemCommand { public: ScaleWorldItemsCommand(const QList &items, const QPointF &factor, @@ -225,16 +248,14 @@ public: PrimitivesTreeModel *model, QUndoCommand *parent = 0); virtual ~ScaleWorldItemsCommand(); - virtual void undo(); - virtual void redo(); +protected: + virtual void undoChangeItem(int i, AbstractWorldItem *item); + virtual void redoChangeItem(int i, AbstractWorldItem *item); + private: - const QList m_listPaths; const QPointF m_factor; const QPointF m_pivot; - PrimitivesTreeModel *const m_model; - WorldEditorScene *m_scene; - bool m_firstRun; }; /** @@ -242,7 +263,7 @@ private: @brief @details */ -class TurnWorldItemsCommand: public QUndoCommand +class TurnWorldItemsCommand: public AbstractWorldItemCommand { public: TurnWorldItemsCommand(const QList &items, const qreal angle, @@ -250,15 +271,13 @@ public: QUndoCommand *parent = 0); virtual ~TurnWorldItemsCommand(); - virtual void undo(); - virtual void redo(); +protected: + virtual void undoChangeItem(int i, AbstractWorldItem *item); + virtual void redoChangeItem(int i, AbstractWorldItem *item); + private: - const QList m_listPaths; const qreal m_angle; - PrimitivesTreeModel *const m_model; - WorldEditorScene *m_scene; - bool m_firstRun; }; /** @@ -266,7 +285,7 @@ private: @brief @details */ -class ShapeWorldItemsCommand: public QUndoCommand +class ShapeWorldItemsCommand: public AbstractWorldItemCommand { public: ShapeWorldItemsCommand(const QList &items, const QList &polygons, @@ -274,16 +293,14 @@ public: QUndoCommand *parent = 0); virtual ~ShapeWorldItemsCommand(); - virtual void undo(); - virtual void redo(); +protected: + virtual void undoChangeItem(int i, AbstractWorldItem *item); + virtual void redoChangeItem(int i, AbstractWorldItem *item); + private: - const QList m_listPaths; const QList m_redoPolygons; const QList m_undoPolygons; - PrimitivesTreeModel *const m_model; - WorldEditorScene *m_scene; - bool m_firstRun; }; } /* namespace WorldEditor */ From eb3c9d2b9060766b9cb6f4df80830112da822521 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Thu, 18 Aug 2011 01:37:39 +0300 Subject: [PATCH 64/89] Changed: #1302 The value angle can save in file. --HG-- branch : gsoc2011-worldeditorqt --- .../src/plugins/world_editor/world_editor_actions.cpp | 5 ++++- .../src/plugins/world_editor/world_editor_plugin.cpp | 2 +- .../src/plugins/world_editor/world_editor_scene_item.cpp | 9 +++++++-- .../src/plugins/world_editor/world_editor_scene_item.h | 2 ++ 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp index b0a201980..b22e3fe64 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp @@ -93,7 +93,7 @@ void addNewGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *mode qreal radius = 0; if (primitive->getPropertyByName ("radius", strRadius)) radius = atof(strRadius.c_str()); - + qreal angle = ((2 * NLMISC::Pi - primPoint->Angle) * 180 / NLMISC::Pi); item = scene->addWorldItemPoint(QPointF(vec->x, -vec->y + cellSize), primPoint->Angle, radius, showArrow); break; @@ -511,8 +511,11 @@ void AbstractWorldItemCommand::updatePrimitiveData(AbstractWorldItem *item) { case NLLIGO::CPrimitiveClass::Point: { + qreal angle = static_cast(item)->angle(); + angle = 2 * NLMISC::Pi - (angle * NLMISC::Pi / 180.0); NLLIGO::CPrimPoint *point = static_cast(primitive); point->Point = vPoints.front(); + point->Angle = angle; break; } case NLLIGO::CPrimitiveClass::Path: diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_plugin.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_plugin.cpp index 8699bfb67..23b51e9e3 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_plugin.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_plugin.cpp @@ -110,7 +110,7 @@ QString WorldEditorPlugin::name() const QString WorldEditorPlugin::version() const { - return "0.0.1"; + return "0.1"; } QString WorldEditorPlugin::vendor() const diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.cpp index 28c933d39..b4d01be65 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.cpp @@ -91,7 +91,7 @@ bool AbstractWorldItem::isShapeChanged() const WorldItemPoint::WorldItemPoint(const QPointF &point, const qreal angle, const qreal radius, bool showArrow, QGraphicsItem *parent) : AbstractWorldItem(parent), - m_angle((2 * NLMISC::Pi - angle) * 180 / NLMISC::Pi), + m_angle(angle), m_radius(radius), m_showArrow(showArrow) { @@ -132,6 +132,11 @@ WorldItemPoint::~WorldItemPoint() { } +qreal WorldItemPoint::angle() const +{ + return m_angle; +} + void WorldItemPoint::rotateOn(const QPointF &pivot, const qreal deltaAngle) { prepareGeometryChange(); @@ -167,6 +172,7 @@ void WorldItemPoint::scaleOn(const QPointF &pivot, const QPointF &factor) void WorldItemPoint::turnOn(const qreal angle) { m_angle += angle; + m_angle -= floor(m_angle / 360) * 360; update(); } @@ -873,7 +879,6 @@ void WorldItemSubPoint::scaleOn(const QPointF &pivot, const QPointF &factor) // TODO scaledPolygon.translate(scenePos() - pivot); - //scaledPolygon.translate(-pivot); QTransform trans; trans = trans.scale(factor.x(), factor.y()); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h index b42138833..7268b6d03 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h @@ -113,6 +113,8 @@ public: bool showArrow, QGraphicsItem *parent = 0); virtual ~WorldItemPoint(); + qreal angle() const; + virtual void rotateOn(const QPointF &pivot, const qreal deltaAngle); virtual void scaleOn(const QPointF &pivot, const QPointF &factor); virtual void turnOn(const qreal angle); From da6828daf045fad50e8f4206c75ee1dbca4d3213 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Fri, 19 Aug 2011 00:14:40 +0300 Subject: [PATCH 65/89] Changed: #1301 Fix typos in comments/code. --HG-- branch : gsoc2011-worldeditorqt --- .../plugins/landscape_editor/builder_zone.cpp | 43 +++++++----- .../plugins/landscape_editor/builder_zone.h | 31 ++++++++- .../landscape_editor/builder_zone_base.h | 4 +- .../landscape_editor/landscape_actions.cpp | 39 +++-------- .../landscape_editor/landscape_actions.h | 65 ++++++++----------- .../landscape_editor_constants.h | 1 - .../landscape_editor_plugin.cpp | 3 +- .../landscape_editor_plugin.h | 1 - .../landscape_editor_window.cpp | 1 - .../landscape_editor_window.h | 1 - .../plugins/landscape_editor/landscape_view.h | 10 +++ .../landscape_editor/list_zones_model.h | 6 +- .../landscape_editor/list_zones_widget.h | 9 ++- .../landscape_editor/pixmap_database.cpp | 5 +- .../landscape_editor/pixmap_database.h | 3 +- .../project_settings_dialog.cpp | 1 - .../project_settings_dialog.h | 1 - .../landscape_editor/snapshot_dialog.cpp | 1 - .../landscape_editor/snapshot_dialog.h | 4 -- .../landscape_editor/zone_region_editor.h | 6 +- 20 files changed, 117 insertions(+), 118 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp index 62ed76e89..f9aec3e3b 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp @@ -85,7 +85,7 @@ void ZoneBuilder::actionLigoTile(const LigoData &data, const ZonePosition &zoneP 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()); + // 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)); } @@ -96,7 +96,6 @@ void ZoneBuilder::actionLigoMove(uint index, sint32 deltaX, sint32 deltaY) return; checkBeginMacro(); - nlinfo("ligoMove"); //m_undoStack->push(new LigoMoveCommand(index, deltaX, deltaY, this)); } @@ -106,7 +105,7 @@ void ZoneBuilder::actionLigoResize(uint index, sint32 newMinX, sint32 newMaxX, s return; checkBeginMacro(); - nlinfo(QString("minX=%1 maxX=%2 minY=%3 maxY=%4").arg(newMinX).arg(newMaxX).arg(newMinY).arg(newMaxY).toStdString().c_str()); + // 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)); } @@ -274,7 +273,7 @@ int ZoneBuilder::createZoneRegion(const QString &fileName) landItem.zoneRegionObject = new ZoneRegionObject(); landItem.zoneRegionObject->load(fileName.toStdString()); - if (!checkOverlaps(landItem.zoneRegionObject->ligoZoneRegion())) + if (checkOverlaps(landItem.zoneRegionObject->ligoZoneRegion())) { delete landItem.zoneRegionObject; return -1; @@ -334,7 +333,11 @@ int ZoneBuilder::currentIdZoneRegion() const ZoneRegionObject *ZoneBuilder::currentZoneRegion() const { - return m_landscapeMap.value(m_currentZoneRegion).zoneRegionObject; + ZoneRegionObject *result = 0; + if (m_landscapeMap.contains(m_currentZoneRegion)) + result = m_landscapeMap.value(m_currentZoneRegion).zoneRegionObject; + + return result; } int ZoneBuilder::countZoneRegion() const @@ -344,17 +347,23 @@ int ZoneBuilder::countZoneRegion() const ZoneRegionObject *ZoneBuilder::zoneRegion(int id) const { - return m_landscapeMap.value(id).zoneRegionObject; + ZoneRegionObject *result = 0; + if (m_landscapeMap.contains(id)) + result = m_landscapeMap.value(id).zoneRegionObject; + + return result; } void ZoneBuilder::ligoData(LigoData &data, const ZonePosition &zonePos) { - m_landscapeMap.value(zonePos.region).zoneRegionObject->ligoData(data, zonePos.x, zonePos.y); + if (m_landscapeMap.contains(zonePos.region)) + 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); + if (m_landscapeMap.contains(zonePos.region)) + m_landscapeMap.value(zonePos.region).zoneRegionObject->setLigoData(data, zonePos.x, zonePos.y); } bool ZoneBuilder::initZoneBank (const QString &pathName) @@ -390,14 +399,10 @@ QString ZoneBuilder::dataPath() const bool ZoneBuilder::getZoneMask(sint32 x, sint32 y) { if ((x < m_minX) || (x > m_maxX) || - (y < m_minY) || (y > m_maxY)) - { + (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() @@ -485,7 +490,7 @@ void ZoneBuilder::checkBeginMacro() { m_createdAction = true; m_undoStack->beginMacro(m_titleAction); - m_undoScanRegionCommand = new UndoScanRegionCommand(this, m_landscapeScene); + m_undoScanRegionCommand = new UndoScanRegionCommand(true, this, m_landscapeScene); m_undoStack->push(m_undoScanRegionCommand); } } @@ -494,9 +499,13 @@ void ZoneBuilder::checkEndMacro() { if (m_createdAction) { - RedoScanRegionCommand *redoScanRegionCommand = new RedoScanRegionCommand(this, m_landscapeScene); + UndoScanRegionCommand *redoScanRegionCommand = new UndoScanRegionCommand(false, this, m_landscapeScene); + + // Sets list positions in which need apply changes m_undoScanRegionCommand->setScanList(m_zonePositionList); redoScanRegionCommand->setScanList(m_zonePositionList); + + // Adds command in the stack m_undoStack->push(redoScanRegionCommand); m_undoStack->endMacro(); } @@ -517,11 +526,11 @@ bool ZoneBuilder::checkOverlaps(const NLLIGO::CZoneRegion &newZoneRegion) { const std::string &zoneName = newZoneRegion.getName(x, y); if ((zoneName != STRING_UNUSED) && (zoneName != STRING_OUT_OF_BOUND)) - return false; + return true; } } } - return true; + return false; } } /* namespace LandscapeEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h index d16008a5f..41983641f 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h @@ -59,17 +59,25 @@ public: ZoneBuilder(LandscapeScene *landscapeScene, ListZonesWidget *listZonesWidget = 0, QUndoStack *undoStack = 0); ~ZoneBuilder(); - /// Init zoneBank and init zone pixmap database + /// Inits zoneBank and init zone pixmap database bool init(const QString &pathName, bool displayProgress = false); void calcMask(); + + /// @return false if in point (x, y) placed zone brick, else true bool getZoneMask (sint32 x, sint32 y); + bool getZoneAmongRegions(ZonePosition &zonePos, BuilderZoneRegion *builderZoneRegionFrom, sint32 x, sint32 y); /// Ligo Actions /// @{ + + /// Adds the LigoTileCommand in undo stack void actionLigoTile(const LigoData &data, const ZonePosition &zonePos); + void actionLigoMove(uint index, sint32 deltaX, sint32 deltaY); + + /// Adds the LigoResizeCommand in undo stack void actionLigoResize(uint index, sint32 newMinX, sint32 newMaxX, sint32 newMinY, sint32 newMaxY); /// @} @@ -82,11 +90,24 @@ public: /// Zone Region /// @{ + + /// Creates empty zone region and adds in the workspace + /// @return id zone region int createZoneRegion(); + + /// Loads zone region from file @fileName and adds in the workspace. + /// @return id zone region int createZoneRegion(const QString &fileName); + + /// Unloads zone region from the workspace void deleteZoneRegion(int id); + + /// Sets the current zone region with @id void setCurrentZoneRegion(int id); + + /// @return id the current zone region, if workspace is empty then returns (-1) int currentIdZoneRegion() const; + ZoneRegionObject *currentZoneRegion() const; int countZoneRegion() const; ZoneRegionObject *zoneRegion(int id) const; @@ -106,12 +127,18 @@ public: private: - /// Scan ./zoneligos dir and add all *.ligozone files to zoneBank + /// Scans ./zoneligos dir and add all *.ligozone files to zoneBank bool initZoneBank (const QString &path); + /// Checks enabled beginMacro mode for undo stack, if false, then enables mode void checkBeginMacro(); + + /// Checks enabled on beginMacro mode for undo stack, if true, then adds UndoScanRegionCommand + /// in undo stack and disables beginMacro mode void checkEndMacro(); + /// Checks intersects between them zone regions + /// @return true if newZoneRegion intersects with loaded zone regions, else return false bool checkOverlaps(const NLLIGO::CZoneRegion &newZoneRegion); struct LandscapeItem diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_base.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_base.h index 4c9e501eb..8ea7f79a3 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_base.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_base.h @@ -67,8 +67,8 @@ struct ZonePosition }; /** -@class ZoneBuilder -@brief ZoneBuilder contains all the shared data between the tools and the engine. +@class ZoneBuilderBase +@brief ZoneBuilderBase contains all the shared data between the tools and the engine. @details ZoneBank contains the macro zones that is composed of several zones plus a mask. PixmapDatabase contains the graphics for the zones */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp index 4fcf36efe..dc8b003c7 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp @@ -93,8 +93,9 @@ void LigoTileCommand::redo () m_zoneBuilder->setLigoData(m_newLigoData, m_zonePos); } -UndoScanRegionCommand::UndoScanRegionCommand(ZoneBuilder *zoneBuilder, LandscapeScene *scene, QUndoCommand *parent) +UndoScanRegionCommand::UndoScanRegionCommand(bool direction, ZoneBuilder *zoneBuilder, LandscapeScene *scene, QUndoCommand *parent) : QUndoCommand(parent), + m_direction(direction), m_zoneBuilder(zoneBuilder), m_scene(scene) { @@ -112,45 +113,21 @@ void UndoScanRegionCommand::setScanList(const QList &zonePositionL 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)); - } + if (m_direction) + applyChanges(); } void UndoScanRegionCommand::redo() { + if (!m_direction) + applyChanges(); } -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 &zonePositionList) -{ - m_zonePositionList = zonePositionList; -} - -void RedoScanRegionCommand::undo() -{ -} - -void RedoScanRegionCommand::redo() +void UndoScanRegionCommand::applyChanges() { for (int i = 0; i < m_zonePositionList.size(); ++i) m_scene->deleteItemZone(m_zonePositionList.at(i)); + for (int i = 0; i < m_zonePositionList.size(); ++i) { LigoData data; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h index c4afcc801..a21bece5d 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h @@ -32,6 +32,11 @@ namespace LandscapeEditor { +/** +@class OpenLandscapeCommand +@brief +@details +*/ class OpenLandscapeCommand: public QUndoCommand { public: @@ -45,6 +50,11 @@ private: QString m_fileName; }; +/** +@class NewLandscapeCommand +@brief +@details +*/ class NewLandscapeCommand: public QUndoCommand { public: @@ -56,7 +66,11 @@ public: private: }; -// Modify the landscape +/** +@class LigoTileCommand +@brief +@details +*/ class LigoTileCommand: public QUndoCommand { public: @@ -76,10 +90,15 @@ private: LandscapeScene *m_scene; }; +/** +@class UndoScanRegionCommand +@brief +@details +*/ class UndoScanRegionCommand: public QUndoCommand { public: - UndoScanRegionCommand(ZoneBuilder *zoneBuilder, LandscapeScene *scene, QUndoCommand *parent = 0); + UndoScanRegionCommand(bool direction, ZoneBuilder *zoneBuilder, LandscapeScene *scene, QUndoCommand *parent = 0); virtual ~UndoScanRegionCommand(); void setScanList(const QList &zonePositionList); @@ -87,49 +106,19 @@ public: virtual void redo(); private: + void applyChanges(); + bool m_direction; QList 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 &zonePositionList); - virtual void undo(); - virtual void redo(); - -private: - - QList 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; -}; +/** +@class LigoResizeCommand +@brief +@details */ -// Modify the landscape class LigoResizeCommand: public QUndoCommand { public: diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_constants.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_constants.h index 76b91dad5..92845abb8 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_constants.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_constants.h @@ -1,5 +1,4 @@ // Object Viewer Qt - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited // Copyright (C) 2011 Dzmitry Kamiahin // // This program is free software: you can redistribute it and/or modify diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_plugin.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_plugin.cpp index 401256ce6..e7665b42f 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_plugin.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_plugin.cpp @@ -1,5 +1,4 @@ // Object Viewer Qt - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited // Copyright (C) 2011 Dzmitry Kamiahin // // This program is free software: you can redistribute it and/or modify @@ -75,7 +74,7 @@ QString LandscapeEditorPlugin::name() const QString LandscapeEditorPlugin::version() const { - return "0.1"; + return "0.8"; } QString LandscapeEditorPlugin::vendor() const diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_plugin.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_plugin.h index 8f9f811cf..4515da8be 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_plugin.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_plugin.h @@ -1,5 +1,4 @@ // Object Viewer Qt - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited // Copyright (C) 2011 Dzmitry Kamiahin // // This program is free software: you can redistribute it and/or modify diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp index b3110a0e5..69b27c660 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp @@ -1,5 +1,4 @@ // Object Viewer Qt - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited // Copyright (C) 2011 Dzmitry Kamiahin // // This program is free software: you can redistribute it and/or modify diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h index 67768e39a..92745365b 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h @@ -1,5 +1,4 @@ // Object Viewer Qt - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited // Copyright (C) 2011 Dzmitry Kamiahin // // This program is free software: you can redistribute it and/or modify diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h index 5ce1fb3a7..462e6ecfb 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h @@ -27,6 +27,11 @@ namespace LandscapeEditor { +/** +@class LandscapeView +@brief Provides graphics view for viewing zone regions. +@details Also provides zooming, panning and displaying grid +*/ class LANDSCAPE_EDITOR_EXPORT LandscapeView: public QGraphicsView { Q_OBJECT @@ -42,11 +47,16 @@ public: bool isVisibleGrid() const; public Q_SLOTS: + + /// Enable/disable displaying grid. void setVisibleGrid(bool visible); + + /// Enable/disable displaying text(coord.) above each zone bricks. void setVisibleText(bool visible); private Q_SLOTS: protected: + //Take over the interaction virtual void wheelEvent(QWheelEvent *event); virtual void mousePressEvent(QMouseEvent *event); virtual void mouseMoveEvent(QMouseEvent *event); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_model.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_model.h index 6c53ab4bc..e4682ebea 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_model.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_model.h @@ -35,8 +35,8 @@ class PixmapDatabase; /** @class ListZonesModel -@brief ListZonesModel contains the small images for QListView -@details +@brief ListZonesModel is used for managed list bricks by ListZonesWidget +@details ListZonesModel contains the small images for QListView */ class ListZonesModel : public QAbstractListModel { @@ -55,7 +55,7 @@ public: /// Value should be set before calling rebuildModel void setScaleRatio(int scaleRatio); - /// Unload all images and reset model + /// Delete all small images and reset model void resetModel(); /// Set current list zones which will be available in QListView diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h index 7298bbe3c..091c33908 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h @@ -1,5 +1,4 @@ // Object Viewer Qt - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited // Copyright (C) 2011 Dzmitry Kamiahin // // This program is free software: you can redistribute it and/or modify @@ -45,16 +44,16 @@ public: void updateUi(); - // Set zone builder, call this method before using this class + /// Set zone builder, call this method before using this class void setZoneBuilder(ZoneBuilder *zoneBuilder); - // Get current zone name which user selected from list. + /// 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). + /// 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). + /// Get current flip value which user selected (Flip 0-false, 1-true). int currentFlip(); bool isNotPropogate() const; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.cpp index d3dbd646d..83e581ff3 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.cpp @@ -39,6 +39,7 @@ PixmapDatabase::PixmapDatabase(int textureSize) : m_textureSize(textureSize), m_errorPixmap(0) { + // Create pixmap for case if pixmap and LIGO files not found m_errorPixmap = new QPixmap(QSize(m_textureSize, m_textureSize)); QPainter painter(m_errorPixmap); painter.setRenderHint(QPainter::Antialiasing, true); @@ -46,7 +47,7 @@ PixmapDatabase::PixmapDatabase(int textureSize) 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.")); + QObject::tr("Pixmap and LIGO files not found.")); painter.end(); } @@ -84,7 +85,7 @@ bool PixmapDatabase::loadPixmaps(const QString &zonePath, NLLIGO::CZoneBank &zon QPixmap *pixmap = new QPixmap(zonePath + zonePixmapName + ".png"); if (pixmap->isNull()) { - // Generate filled pixmap + // Generate filled pixmap if could not load pixmap QPixmap *emptyPixmap = new QPixmap(QSize(sizeX * m_textureSize, sizeY * m_textureSize)); QPainter painter(emptyPixmap); painter.setRenderHint(QPainter::Antialiasing, true); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.h index a9d4383ad..ce0b2a3bf 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.h @@ -52,7 +52,8 @@ public: QStringList listPixmaps() const; /// Get original pixmap - /// @return QPixmap* if the image is in the database ; otherwise returns 0. + /// @return QPixmap* if the image is in the database ; + /// otherwise returns pixmap which contains error message. QPixmap *pixmap(const QString &zoneName) const; int textureSize() const; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.cpp index 3acd3ff66..f3eedb8a6 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.cpp @@ -1,5 +1,4 @@ // Object Viewer Qt - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited // Copyright (C) 2011 Dzmitry Kamiahin // // This program is free software: you can redistribute it and/or modify diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.h index abb93ab81..ecad06f58 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.h @@ -1,5 +1,4 @@ // Object Viewer Qt - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited // Copyright (C) 2011 Dzmitry Kamiahin // // This program is free software: you can redistribute it and/or modify diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/snapshot_dialog.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/snapshot_dialog.cpp index ab2579722..aeccd21b2 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/snapshot_dialog.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/snapshot_dialog.cpp @@ -1,5 +1,4 @@ // Object Viewer Qt - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited // Copyright (C) 2011 Dzmitry Kamiahin // // This program is free software: you can redistribute it and/or modify diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/snapshot_dialog.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/snapshot_dialog.h index b66133a07..34db0e4a2 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/snapshot_dialog.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/snapshot_dialog.h @@ -1,5 +1,4 @@ // Object Viewer Qt - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited // Copyright (C) 2011 Dzmitry Kamiahin // // This program is free software: you can redistribute it and/or modify @@ -40,9 +39,6 @@ public: int widthSnapshot() const; int heightSnapshot() const; -private Q_SLOTS: - - private: Ui::SnapshotDialog m_ui; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.h index 91b2d66c1..e40aba9d4 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.h @@ -28,8 +28,6 @@ // STL includes #include -// Qt includes - namespace LandscapeEditor { @@ -80,7 +78,7 @@ struct LigoData /** @class ZoneRegionObject -@brief +@brief The class contains NLLIGO::CZoneRegion object and provides basic operations above it @details */ class LANDSCAPE_EDITOR_EXPORT ZoneRegionObject @@ -115,7 +113,7 @@ public: /// 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 + /// Helper flag to know if the zone region has been modified /// @{ bool isModified() const; From 3ccb85e0a40066fe56cdc4b9f451d58da93d5881 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Sat, 20 Aug 2011 16:10:35 +0300 Subject: [PATCH 66/89] Changed: #1302 Added "delete primitive" undo command. --HG-- branch : gsoc2011-worldeditorqt --- .../landscape_editor/pixmap_database.h | 2 +- .../object_viewer/object_viewer_plugin.cpp | 2 +- .../plugins/world_editor/primitive_item.cpp | 13 +++ .../src/plugins/world_editor/primitive_item.h | 3 + .../plugins/world_editor/primitives_model.cpp | 34 ++++---- .../plugins/world_editor/primitives_model.h | 8 +- .../plugins/world_editor/primitives_view.cpp | 10 ++- .../world_editor/world_editor_actions.cpp | 81 ++++++++++++++++++- .../world_editor/world_editor_actions.h | 32 +++++++- .../world_editor/world_editor_constants.h | 1 + .../plugins/world_editor/world_editor_misc.h | 3 - .../world_editor/world_editor_window.cpp | 8 +- .../world_editor/world_editor_window.ui | 15 +--- 13 files changed, 166 insertions(+), 46 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.h index ce0b2a3bf..15b26e474 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.h @@ -52,7 +52,7 @@ public: QStringList listPixmaps() const; /// Get original pixmap - /// @return QPixmap* if the image is in the database ; + /// @return QPixmap* if the image is in the database ; /// otherwise returns pixmap which contains error message. QPixmap *pixmap(const QString &zoneName) const; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/object_viewer_plugin.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/object_viewer_plugin.cpp index f82789e66..4bc976571 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/object_viewer_plugin.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/object_viewer/object_viewer_plugin.cpp @@ -68,7 +68,7 @@ QString ObjectViewerPlugin::version() const QString ObjectViewerPlugin::vendor() const { - return Core::Constants::OVQT_VENDOR; + return "GSoC2010_dnk-88"; } QString ObjectViewerPlugin::description() const diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.cpp index e867f1368..05b200960 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.cpp @@ -34,6 +34,7 @@ namespace WorldEditor Node::Node() : m_parent(0) { + setData(Constants::PRIMITIVE_IS_VISIBLE, true); } Node::~Node() @@ -102,6 +103,18 @@ void Node::insertChildNodeAfter(Node *node, Node *after) node->m_parent = this; } +void Node::insertChildNode(int pos, Node *node) +{ + // Node is already a child + nlassert(!m_children.contains(node)); + + // Node already has a parent + nlassert(!m_children.contains(node)); + + m_children.insert(pos, node); + node->m_parent = this; +} + void Node::removeChildNode(Node *node) { nlassert(m_children.contains(node)); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h index 300973c55..164ee035f 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h @@ -72,6 +72,9 @@ public: /// Insert node in back of the node pointed to by the pointer after. void insertChildNodeAfter(Node *node, Node *after); + /// Insert node in pos + void insertChildNode(int pos, Node *node); + /// Return the node at index position row in the child list. Node *child(int row); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.cpp index 690e7db08..d40453dee 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.cpp @@ -214,7 +214,7 @@ Path PrimitivesTreeModel::createLandscapeNode(const QString &fileName) } -Path PrimitivesTreeModel::createRootPrimitiveNode(const QString &fileName, NLLIGO::CPrimitives *primitives) +Path PrimitivesTreeModel::createRootPrimitiveNode(const QString &fileName, NLLIGO::CPrimitives *primitives, int pos) { if (m_worldEditNode == 0) createWorldEditNode("NewWorldEdit"); @@ -223,42 +223,48 @@ Path PrimitivesTreeModel::createRootPrimitiveNode(const QString &fileName, NLLIG if (!fileName.isEmpty()) name = fileName; + int insPos = pos; + // Get position - int pos = m_worldEditNode->childCount(); + if (pos == AtTheEnd) + insPos = m_worldEditNode->childCount(); QModelIndex parentIndex = index(0, 0, QModelIndex()); // Add root node in tree model - beginInsertRows(parentIndex, pos, pos); + beginInsertRows(parentIndex, insPos, insPos); RootPrimitiveNode *newNode = new RootPrimitiveNode(name, primitives); - m_worldEditNode->appendChildNode(newNode); + m_worldEditNode->insertChildNode(insPos, newNode); endInsertRows(); newNode->setData(Constants::PRIMITIVE_FILE_IS_CREATED, !fileName.isEmpty()); newNode->setData(Constants::PRIMITIVE_IS_MODIFIED, false); - QModelIndex rootPrimIndex = index(pos, 0, parentIndex); + QModelIndex rootPrimIndex = index(insPos, 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); + createChildNodes(childPrim, i, rootPrimIndex); } return pathFromIndex(rootPrimIndex); } -Path PrimitivesTreeModel::createPrimitiveNode(NLLIGO::IPrimitive *primitive, const Path &parent) +Path PrimitivesTreeModel::createPrimitiveNode(NLLIGO::IPrimitive *primitive, const Path &parent, int pos) { QModelIndex parentIndex = pathToIndex(parent); Node *parentNode = static_cast(parentIndex.internalPointer()); - int pos = parentNode->childCount(); - createChildNodes(primitive, parentIndex); + int insPos = pos; + if (pos == AtTheEnd) + insPos = parentNode->childCount(); + + createChildNodes(primitive, insPos, parentIndex); - return pathFromIndex(index(pos, 0, parentIndex)); + return pathFromIndex(index(insPos, 0, parentIndex)); } void PrimitivesTreeModel::deleteNode(const Path &path) @@ -271,16 +277,14 @@ void PrimitivesTreeModel::deleteNode(const Path &path) removeChildNodes(node, parentIndex); } -void PrimitivesTreeModel::createChildNodes(NLLIGO::IPrimitive *primitive, const QModelIndex &parent) +void PrimitivesTreeModel::createChildNodes(NLLIGO::IPrimitive *primitive, int pos, const QModelIndex &parent) { Node *parentNode = static_cast(parent.internalPointer()); - int pos = parentNode->childCount(); - // Add node in the tree model beginInsertRows(parent, pos, pos); PrimitiveNode *newNode = new PrimitiveNode(primitive); - parentNode->appendChildNode(newNode); + parentNode->insertChildNode(pos, newNode); endInsertRows(); // Scan childs items and add in the tree model @@ -289,7 +293,7 @@ void PrimitivesTreeModel::createChildNodes(NLLIGO::IPrimitive *primitive, const { NLLIGO::IPrimitive *childPrim; primitive->getChild(childPrim, i); - createChildNodes(childPrim, childIndex); + createChildNodes(childPrim, i, childIndex); } } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.h index c3c6a3e51..c9d59e848 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.h @@ -34,6 +34,8 @@ namespace WorldEditor class Node; class WorldEditNode; +const int AtTheEnd = -1; + typedef QPair PathItem; /* @typedef Path @@ -81,16 +83,16 @@ public: 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); + Path createRootPrimitiveNode(const QString &fileName, NLLIGO::CPrimitives *primitives, int pos = AtTheEnd); /// Add new primitive node and all sub-primitives in the tree model. - Path createPrimitiveNode(NLLIGO::IPrimitive *primitive, const Path &parent); + Path createPrimitiveNode(NLLIGO::IPrimitive *primitive, const Path &parent, int pos = AtTheEnd); /// 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 createChildNodes(NLLIGO::IPrimitive *primitive, int pos, const QModelIndex &parent); void removeChildNodes(Node *node, const QModelIndex &parent); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.cpp index ca329b25b..b1f5ffda9 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.cpp @@ -66,7 +66,7 @@ PrimitivesView::PrimitivesView(QWidget *parent) m_newPrimitiveAction = new QAction("New primitive", this); m_deleteAction = new QAction("Delete", this); - m_deleteAction->setEnabled(false); + //m_deleteAction->setEnabled(false); m_selectChildrenAction = new QAction("Select children", this); @@ -243,6 +243,14 @@ void PrimitivesView::deletePrimitives() nlassert(m_primitivesTreeModel); QModelIndexList indexList = selectionModel()->selectedRows(); + + QModelIndex index = indexList.first(); + + PrimitiveNode *node = static_cast(index.internalPointer()); + + if (node->primitiveClass()->Deletable) + m_undoStack->push(new DeletePrimitiveCommand(index, m_primitivesTreeModel, m_worldEditorScene, this)); + } void PrimitivesView::addNewPrimitiveByClass(int value) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp index b22e3fe64..635c7342b 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp @@ -95,7 +95,7 @@ void addNewGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *mode radius = atof(strRadius.c_str()); qreal angle = ((2 * NLMISC::Pi - primPoint->Angle) * 180 / NLMISC::Pi); item = scene->addWorldItemPoint(QPointF(vec->x, -vec->y + cellSize), - primPoint->Angle, radius, showArrow); + angle, radius, showArrow); break; } case NLLIGO::CPrimitiveClass::Path: @@ -430,6 +430,85 @@ void AddPrimitiveByClassCommand::redo() addNewGraphicsItems(m_model->pathToIndex(m_newPrimIndex), m_model, m_scene); } +DeletePrimitiveCommand::DeletePrimitiveCommand(const QModelIndex &index, PrimitivesTreeModel *model, + WorldEditorScene *scene, QTreeView *view, QUndoCommand *parent) + : QUndoCommand(parent), + m_scene(scene), + m_model(model), + m_view(view) +{ + setText("Delete primitive"); + + // Save path to primitive + m_path = m_model->pathFromIndex(index); + m_parentPath = m_model->pathFromIndex(index.parent()); + + PrimitiveNode *node = static_cast(index.internalPointer()); + + NLLIGO::IPrimitive *primitive = node->primitive(); + + // Backup primitive + m_oldPrimitive = primitive->copy(); + + // Backup position primitive + primitive->getParent()->getChildId(m_posPrimitive, primitive); +} + +DeletePrimitiveCommand::~DeletePrimitiveCommand() +{ + delete m_oldPrimitive; +} + +void DeletePrimitiveCommand::undo() +{ + m_scene->setEnabledEditPoints(false); + m_view->selectionModel()->clearSelection(); + + QModelIndex parentIndex = m_model->pathToIndex(m_parentPath); + PrimitiveNode *parentNode = static_cast(parentIndex.internalPointer()); + + // set the primitive context + NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = parentNode->rootPrimitiveNode()->primitives(); + + NLLIGO::IPrimitive *newPrimitive = m_oldPrimitive->copy(); + if (!parentNode->primitive()->insertChild(newPrimitive, m_posPrimitive)) + nlerror("Primitive can't insert, m_posPrimitive is not a valid."); + + // Insert primitive node in tree model + Path newPath = m_model->createPrimitiveNode(newPrimitive, m_parentPath, m_path.back().first); + + // Scan graphics model + addNewGraphicsItems(m_model->pathToIndex(newPath), m_model, m_scene); + + // unset the context + NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = NULL; +} + +void DeletePrimitiveCommand::redo() +{ + m_scene->setEnabledEditPoints(false); + m_view->selectionModel()->clearSelection(); + + QModelIndex index = m_model->pathToIndex(m_path); + PrimitiveNode *node = static_cast(index.internalPointer()); + NLLIGO::IPrimitive *primitive = node->primitive(); + + // Removes all graphics items + removeGraphicsItems(index, m_model, m_scene); + + // set the primitive context + NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = node->rootPrimitiveNode()->primitives(); + + // Delete primitive + Utils::deletePrimitive(primitive); + + // unset the context + NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = NULL; + + // Remove primitive from tree model + m_model->deleteNode(m_path); +} + AbstractWorldItemCommand::AbstractWorldItemCommand(const QList &items, WorldEditorScene *scene, PrimitivesTreeModel *model, diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h index 17f19fbca..15a553822 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h @@ -156,9 +156,33 @@ private: float m_delta; const QString m_className; Path m_parentIndex, m_newPrimIndex; - WorldEditorScene *m_scene; - PrimitivesTreeModel *m_model; - QTreeView *m_view; + WorldEditorScene *const m_scene; + PrimitivesTreeModel *const m_model; + QTreeView *const m_view; +}; + +/** +@class DeletePrimitiveCommand +@brief +@details +*/ +class DeletePrimitiveCommand: public QUndoCommand +{ +public: + DeletePrimitiveCommand(const QModelIndex &index, PrimitivesTreeModel *model, + WorldEditorScene *scene, QTreeView *view, QUndoCommand *parent = 0); + virtual ~DeletePrimitiveCommand(); + + virtual void undo(); + virtual void redo(); +private: + + Path m_path, m_parentPath; + uint m_posPrimitive; + NLLIGO::IPrimitive *m_oldPrimitive; + WorldEditorScene *const m_scene; + PrimitivesTreeModel *const m_model; + QTreeView *const m_view; }; /** @@ -186,7 +210,7 @@ private: const QList m_listPaths; PrimitivesTreeModel *const m_model; - WorldEditorScene *m_scene; + WorldEditorScene *const m_scene; bool m_firstRun; }; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_constants.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_constants.h index 9a7a834d6..0e27301d5 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_constants.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_constants.h @@ -30,6 +30,7 @@ const int GRAPHICS_DATA_QT4_2D = USER_TYPE + 3; const int GRAPHICS_DATA_NEL3D = USER_TYPE + 4; const int PRIMITIVE_IS_MODIFIED = USER_TYPE + 5; const int PRIMITIVE_FILE_IS_CREATED = USER_TYPE + 6; +const int PRIMITIVE_IS_VISIBLE = USER_TYPE + 7; //settings const char *const WORLD_EDITOR_SECTION = "WorldEditor"; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_misc.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_misc.h index 2e7fc93b1..4163ae2e0 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_misc.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_misc.h @@ -65,9 +65,6 @@ NLLIGO::IPrimitive *createPrimitive(const char *className, const char *primName, const std::vector &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); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp index 2df27d7c7..ba5543776 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp @@ -74,7 +74,6 @@ WorldEditorWindow::WorldEditorWindow(QWidget *parent) 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)); @@ -95,8 +94,6 @@ WorldEditorWindow::WorldEditorWindow(QWidget *parent) m_modeMapper->setMapping(m_ui.scaleAction, 3); connect(m_ui.turnAction, SIGNAL(triggered()), m_modeMapper, SLOT(map())); m_modeMapper->setMapping(m_ui.turnAction, 4); - connect(m_ui.radiusAction, SIGNAL(triggered()), m_modeMapper, SLOT(map())); - m_modeMapper->setMapping(m_ui.radiusAction, 5); connect(m_modeMapper, SIGNAL(mapped(int)), this, SLOT(setMode(int))); connect(m_ui.pointsAction, SIGNAL(triggered(bool)), m_worldEditorScene, SLOT(setEnabledEditPoints(bool))); @@ -384,9 +381,10 @@ void WorldEditorWindow::readSettings() restoreGeometry(settings->value(Constants::WORLD_WINDOW_GEOMETRY).toByteArray()); // Use OpenGL graphics system instead raster graphics system - if (settings->value(Constants::WORLD_EDITOR_USE_OPENGL, false).toBool()) + if (settings->value(Constants::WORLD_EDITOR_USE_OPENGL, true).toBool()) { - m_oglWidget = new QGLWidget(QGLFormat(QGL::DoubleBuffer)); + //m_oglWidget = new QGLWidget(QGLFormat(QGL::DoubleBuffer)); + m_oglWidget = new QGLWidget(QGLFormat(QGL::DoubleBuffer | QGL::SampleBuffers)); m_ui.graphicsView->setViewport(m_oglWidget); } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui index 870081d47..d6d4edb28 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui @@ -27,6 +27,9 @@ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + QPainter::Antialiasing|QPainter::SmoothPixmapTransform|QPainter::TextAntialiasing + QGraphicsView::NoDrag @@ -72,7 +75,6 @@ - @@ -316,17 +318,6 @@ Turn - - - true - - - false - - - Radius - - true From 0c8bbd7e5b59cbd2e646d91f3d5598de0bfff448 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Mon, 22 Aug 2011 21:53:23 +0300 Subject: [PATCH 67/89] Changed: #1302 Added "unload primitive" and "unload landscape" undo command. Update doxygen comments. --HG-- branch : gsoc2011-worldeditorqt --- .../plugins/landscape_editor/builder_zone.cpp | 4 +- .../plugins/world_editor/primitive_item.cpp | 14 ++- .../src/plugins/world_editor/primitive_item.h | 8 +- .../plugins/world_editor/primitives_model.cpp | 22 ++++- .../plugins/world_editor/primitives_model.h | 7 +- .../plugins/world_editor/primitives_view.cpp | 57 +++++++++-- .../plugins/world_editor/primitives_view.h | 5 +- .../world_editor/project_settings_dialog.cpp | 9 ++ .../world_editor/world_editor_actions.cpp | 99 ++++++++++++++++--- .../world_editor/world_editor_actions.h | 57 ++++++++++- .../world_editor/world_editor_scene.cpp | 10 ++ .../plugins/world_editor/world_editor_scene.h | 21 +++- .../world_editor/world_editor_scene_item.h | 19 +++- .../world_editor/world_editor_window.cpp | 3 + 14 files changed, 293 insertions(+), 42 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp index f9aec3e3b..8e3adf415 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp @@ -399,7 +399,7 @@ QString ZoneBuilder::dataPath() const bool ZoneBuilder::getZoneMask(sint32 x, sint32 y) { if ((x < m_minX) || (x > m_maxX) || - (y < m_minY) || (y > m_maxY)) + (y < m_minY) || (y > m_maxY)) return true; else return m_zoneMask[(x - m_minX) + (y - m_minY) * (1 + m_maxX - m_minX)]; @@ -504,7 +504,7 @@ void ZoneBuilder::checkEndMacro() // Sets list positions in which need apply changes m_undoScanRegionCommand->setScanList(m_zonePositionList); redoScanRegionCommand->setScanList(m_zonePositionList); - + // Adds command in the stack m_undoStack->push(redoScanRegionCommand); m_undoStack->endMacro(); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.cpp index 05b200960..658231b2c 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.cpp @@ -178,7 +178,9 @@ Node::NodeType WorldEditNode::type() const return WorldEditNodeType; } -LandscapeNode::LandscapeNode(const QString &name) +LandscapeNode::LandscapeNode(const QString &name, int id) + : m_id(id), + m_fileName(name) { setData(Qt::DisplayRole, name); setData(Qt::DecorationRole, QIcon(LandscapeEditor::Constants::ICON_ZONE_ITEM)); @@ -188,6 +190,16 @@ LandscapeNode::~LandscapeNode() { } +QString LandscapeNode::fileName() const +{ + return m_fileName; +} + +int LandscapeNode::id() const +{ + return m_id; +} + Node::NodeType LandscapeNode::type() const { return LandscapeNodeType; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h index 164ee035f..f95eff0c0 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h @@ -128,12 +128,18 @@ private: class LandscapeNode: public Node { public: - LandscapeNode(const QString &name); + LandscapeNode(const QString &name, int id); virtual ~LandscapeNode(); + int id() const; + QString fileName() const; + virtual NodeType type() const; private: + + QString m_fileName; + int m_id; }; /* diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.cpp index d40453dee..46436b699 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.cpp @@ -200,17 +200,29 @@ void PrimitivesTreeModel::deleteWorldEditNode() endResetModel(); } -Path PrimitivesTreeModel::createLandscapeNode(const QString &fileName) +bool PrimitivesTreeModel::isWorldEditNodeLoaded() const +{ + if (m_worldEditNode == 0) + return false; + else + return true; +} + +Path PrimitivesTreeModel::createLandscapeNode(const QString &fileName, int id, int pos) { 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); + int insPos = pos; + if (pos == -1) + insPos = 0; + + beginInsertRows(parentIndex, insPos, insPos); + LandscapeNode *newNode = new LandscapeNode(fileName, id); + m_worldEditNode->insertChildNode(insPos, newNode); endInsertRows(); - return pathFromIndex(index(0, 0, index(0, 0, QModelIndex()))); + return pathFromIndex(index(0, 0, index(insPos, 0, QModelIndex()))); } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.h index c9d59e848..d1a883106 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.h @@ -69,18 +69,17 @@ public: /// 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); - - Path pathFromNode(Node *node); - QModelIndex pathToIndex(const Path &path); + Path pathFromNode(Node *node); Node *pathToNode(const Path &path); void createWorldEditNode(const QString &fileName); void deleteWorldEditNode(); + bool isWorldEditNodeLoaded() const; /// Add new landscape node in tree model. - Path createLandscapeNode(const QString &fileName); + Path createLandscapeNode(const QString &fileName, int id, int pos = AtTheEnd); /// Add new root primitive node and all sub-primitives in the tree model. Path createRootPrimitiveNode(const QString &fileName, NLLIGO::CPrimitives *primitives, int pos = AtTheEnd); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.cpp index b1f5ffda9..6395720c5 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.cpp @@ -33,6 +33,7 @@ // Qt includes #include #include +#include #include #include @@ -49,7 +50,6 @@ PrimitivesView::PrimitivesView(QWidget *parent) setContextMenuPolicy(Qt::DefaultContextMenu); m_unloadAction = new QAction("Unload", this); - m_unloadAction->setEnabled(false); m_saveAction = new QAction("Save", this); m_saveAction->setIcon(QIcon(Core::Constants::ICON_SAVE)); @@ -66,7 +66,6 @@ PrimitivesView::PrimitivesView(QWidget *parent) m_newPrimitiveAction = new QAction("New primitive", this); m_deleteAction = new QAction("Delete", this); - //m_deleteAction->setEnabled(false); m_selectChildrenAction = new QAction("Select children", this); @@ -86,6 +85,9 @@ PrimitivesView::PrimitivesView(QWidget *parent) connect(m_deleteAction, SIGNAL(triggered()), this, SLOT(deletePrimitives())); connect(m_saveAction, SIGNAL(triggered()), this, SLOT(save())); connect(m_saveAsAction, SIGNAL(triggered()), this, SLOT(saveAs())); + connect(m_unloadAction, SIGNAL(triggered()), this, SLOT(unload())); + connect(m_showAction, SIGNAL(triggered()), this, SLOT(showPrimitive())); + connect(m_hideAction, SIGNAL(triggered()), this, SLOT(hidePrimitive())); #ifdef Q_OS_DARWIN setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); @@ -186,7 +188,10 @@ void PrimitivesView::selectChildren() QModelIndex parentIndex = indexList.first(); selectionModel()->clearSelection(); - selectChildren(parentIndex); + + QItemSelection itemSelection; + selectChildren(parentIndex, itemSelection); + selectionModel()->select(itemSelection, QItemSelectionModel::Select); } void PrimitivesView::save() @@ -253,6 +258,41 @@ void PrimitivesView::deletePrimitives() } +void PrimitivesView::unload() +{ + nlassert(m_undoStack); + nlassert(m_primitivesTreeModel); + + QModelIndexList indexList = selectionModel()->selectedRows(); + QModelIndex index = indexList.first(); + Node *node = static_cast(index.internalPointer()); + switch (node->type()) + { + case Node::WorldEditNodeType: + { + break; + } + case Node::LandscapeNodeType: + { + m_undoStack->push(new UnloadLandscapeCommand(index, m_primitivesTreeModel, m_zoneBuilder)); + break; + } + case Node::RootPrimitiveNodeType: + { + m_undoStack->push(new UnloadRootPrimitiveCommand(index, m_worldEditorScene, m_primitivesTreeModel, this)); + break; + } + } +} + +void PrimitivesView::showPrimitive() +{ +} + +void PrimitivesView::hidePrimitive() +{ +} + void PrimitivesView::addNewPrimitiveByClass(int value) { nlassert(m_undoStack); @@ -311,21 +351,24 @@ void PrimitivesView::contextMenuEvent(QContextMenuEvent *event) event->accept(); } -void PrimitivesView::selectChildren(const QModelIndex &parent) +void PrimitivesView::selectChildren(const QModelIndex &parent, QItemSelection &itemSelection) { const int rowCount = model()->rowCount(parent); + QItemSelection mergeItemSelection(parent.child(0, 0), parent.child(rowCount - 1, 0)); + itemSelection.merge(mergeItemSelection, QItemSelectionModel::Select); + for (int i = 0; i < rowCount; ++i) { QModelIndex childIndex = parent.child(i, 0); - selectionModel()->select(childIndex, QItemSelectionModel::Select); - selectChildren(childIndex); + if (model()->rowCount(childIndex) != 0) + selectChildren(childIndex, itemSelection); } } void PrimitivesView::fillMenu_WorldEdit(QMenu *menu) { - menu->addAction(m_unloadAction); + //menu->addAction(m_unloadAction); //menu->addAction(m_saveAction); //menu->addAction(m_saveAsAction); menu->addSeparator(); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.h index 3fce65ae7..2b16bc714 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.h @@ -70,6 +70,9 @@ private Q_SLOTS: void save(); void saveAs(); void deletePrimitives(); + void unload(); + void showPrimitive(); + void hidePrimitive(); void addNewPrimitiveByClass(int value); void generatePrimitives(int value); void openItem(int value); @@ -78,7 +81,7 @@ protected: void contextMenuEvent(QContextMenuEvent *event); private: - void selectChildren(const QModelIndex &parent); + void selectChildren(const QModelIndex &parent, QItemSelection &itemSelection); void fillMenu_WorldEdit(QMenu *menu); void fillMenu_Landscape(QMenu *menu); void fillMenu_RootPrimitive(QMenu *menu, const QModelIndex &index); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/project_settings_dialog.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/project_settings_dialog.cpp index 28654864c..42e921106 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/project_settings_dialog.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/project_settings_dialog.cpp @@ -16,12 +16,14 @@ // Project includes #include "project_settings_dialog.h" +#include "world_editor_misc.h" #include "../core/icore.h" #include "../core/core_constants.h" // NeL includes #include +#include // Qt includes #include @@ -36,6 +38,13 @@ ProjectSettingsDialog::ProjectSettingsDialog(const QString &dataPath, QWidget *p { m_ui.setupUi(this); m_ui.pathLineEdit->setText(dataPath); + m_ui.contextComboBox->addItem("empty"); + + // Init the combo box + const std::vector &contexts = Utils::ligoConfig()->getContextString(); + for (uint i = 0; i < contexts.size(); i++) + m_ui.contextComboBox->addItem(QString(contexts[i].c_str())); + setFixedHeight(sizeHint().height()); connect(m_ui.selectPathButton, SIGNAL(clicked()), this, SLOT(selectPath())); } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp index 635c7342b..1e27c9f12 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp @@ -218,7 +218,7 @@ CreateWorldCommand::CreateWorldCommand(const QString &fileName, PrimitivesTreeMo m_fileName(fileName), m_model(model) { - setText("Create new world"); + setText(QObject::tr("Create new world")); } CreateWorldCommand::~CreateWorldCommand() @@ -243,7 +243,7 @@ LoadLandscapeCommand::LoadLandscapeCommand(const QString &fileName, PrimitivesTr m_model(model), m_zoneBuilder(zoneBuilder) { - setText("Load land file"); + setText(QObject::tr("Load land file")); } LoadLandscapeCommand::~LoadLandscapeCommand() @@ -263,7 +263,41 @@ void LoadLandscapeCommand::redo() else m_zoneBuilder->loadZoneRegion(m_fileName, m_id); - landIndex = m_model->createLandscapeNode(m_fileName); + landIndex = m_model->createLandscapeNode(m_fileName, m_id); +} + + +UnloadLandscapeCommand::UnloadLandscapeCommand(const QModelIndex &index, PrimitivesTreeModel *model, + LandscapeEditor::ZoneBuilderBase *zoneBuilder, QUndoCommand *parent) + : QUndoCommand(parent), + m_model(model), + m_zoneBuilder(zoneBuilder) +{ + setText(QObject::tr("Unload land file")); + m_path = m_model->pathFromIndex(index); +} + +UnloadLandscapeCommand::~UnloadLandscapeCommand() +{ +} + +void UnloadLandscapeCommand::undo() +{ + m_zoneBuilder->loadZoneRegion(m_fileName, m_id); + + m_model->createLandscapeNode(m_fileName, m_id, m_path.back().first); +} + +void UnloadLandscapeCommand::redo() +{ + QModelIndex index = m_model->pathToIndex(m_path); + LandscapeNode *node = static_cast(index.internalPointer()); + + m_id = node->id(); + m_fileName = node->fileName(); + + m_zoneBuilder->deleteZoneRegion(m_id); + m_model->deleteNode(m_path); } CreateRootPrimitiveCommand::CreateRootPrimitiveCommand(const QString &fileName, PrimitivesTreeModel *model, QUndoCommand *parent) @@ -271,7 +305,7 @@ CreateRootPrimitiveCommand::CreateRootPrimitiveCommand(const QString &fileName, m_fileName(fileName), m_model(model) { - setText("Create new primitive"); + setText(QObject::tr("Create new primitive")); } CreateRootPrimitiveCommand::~CreateRootPrimitiveCommand() @@ -304,7 +338,7 @@ LoadRootPrimitiveCommand::LoadRootPrimitiveCommand(const QString &fileName, Worl m_model(model), m_view(view) { - setText("Load primitive file"); + setText(QObject::tr("Load primitive file")); } LoadRootPrimitiveCommand::~LoadRootPrimitiveCommand() @@ -358,6 +392,47 @@ void LoadRootPrimitiveCommand::redo() addNewGraphicsItems(m_model->pathToIndex(m_rootPrimIndex), m_model, m_scene); } + +UnloadRootPrimitiveCommand::UnloadRootPrimitiveCommand(const QModelIndex &index, WorldEditorScene *scene, + PrimitivesTreeModel *model, QTreeView *view, QUndoCommand *parent) + : QUndoCommand(parent), + m_scene(scene), + m_model(model), + m_view(view) +{ + setText(QObject::tr("Unload primitive file")); + m_path = m_model->pathFromIndex(index); +} + +UnloadRootPrimitiveCommand::~UnloadRootPrimitiveCommand() +{ +} + +void UnloadRootPrimitiveCommand::undo() +{ + // Disable edit points mode + m_scene->setEnabledEditPoints(false); + + m_path = m_model->createRootPrimitiveNode(m_fileName, m_primitives, m_path.back().first); + + addNewGraphicsItems(m_model->pathToIndex(m_path), m_model, m_scene); +} + +void UnloadRootPrimitiveCommand::redo() +{ + m_scene->setEnabledEditPoints(false); + + m_view->selectionModel()->clearSelection(); + QModelIndex index = m_model->pathToIndex(m_path); + RootPrimitiveNode *node = static_cast(index.internalPointer()); + m_fileName = node->fileName(); + m_primitives = node->primitives(); + + removeGraphicsItems(index, m_model, m_scene); + + m_model->deleteNode(m_path); +} + AddPrimitiveByClassCommand::AddPrimitiveByClassCommand(const QString &className, const Path &parentIndex, WorldEditorScene *scene, PrimitivesTreeModel *model, QTreeView *view, QUndoCommand *parent) : QUndoCommand(parent), @@ -367,7 +442,7 @@ AddPrimitiveByClassCommand::AddPrimitiveByClassCommand(const QString &className, m_model(model), m_view(view) { - setText(QString("Add %1").arg(m_className)); + setText(QObject::tr("Add %1").arg(m_className)); QGraphicsView *graphicsView = m_scene->views().first(); @@ -437,7 +512,7 @@ DeletePrimitiveCommand::DeletePrimitiveCommand(const QModelIndex &index, Primiti m_model(model), m_view(view) { - setText("Delete primitive"); + setText(QObject::tr("Delete primitive")); // Save path to primitive m_path = m_model->pathFromIndex(index); @@ -629,7 +704,7 @@ MoveWorldItemsCommand::MoveWorldItemsCommand(const QList &items : AbstractWorldItemCommand(items, scene, model, parent), m_offset(offset) { - setText("Move item(s)"); + setText(QObject::tr("Move item(s)")); } MoveWorldItemsCommand::~MoveWorldItemsCommand() @@ -652,7 +727,7 @@ RotateWorldItemsCommand::RotateWorldItemsCommand(const QList &i m_angle(angle), m_pivot(pivot) { - setText("Rotate item(s)"); + setText(QObject::tr("Rotate item(s)")); } RotateWorldItemsCommand::~RotateWorldItemsCommand() @@ -675,7 +750,7 @@ ScaleWorldItemsCommand::ScaleWorldItemsCommand(const QList &ite m_factor(factor), m_pivot(pivot) { - setText("Scale item(s)"); + setText(QObject::tr("Scale item(s)")); } ScaleWorldItemsCommand::~ScaleWorldItemsCommand() @@ -698,7 +773,7 @@ TurnWorldItemsCommand::TurnWorldItemsCommand(const QList &items : AbstractWorldItemCommand(items, scene, model, parent), m_angle(angle) { - setText("Turn item(s)"); + setText(QObject::tr("Turn item(s)")); } TurnWorldItemsCommand::~TurnWorldItemsCommand() @@ -722,7 +797,7 @@ ShapeWorldItemsCommand::ShapeWorldItemsCommand(const QList &ite m_redoPolygons(polygons), m_undoPolygons(polygonsFromItems(items)) { - setText("Change shape"); + setText(QObject::tr("Change shape")); } ShapeWorldItemsCommand::~ShapeWorldItemsCommand() diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h index 15a553822..89de14e9a 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.h @@ -95,6 +95,34 @@ private: LandscapeEditor::ZoneBuilderBase *const m_zoneBuilder; }; +/** +@class UnloadLandscapeCommand +@brief +@details +*/ +class UnloadLandscapeCommand: public QUndoCommand +{ +public: + UnloadLandscapeCommand(const QModelIndex &index, PrimitivesTreeModel *model, + LandscapeEditor::ZoneBuilderBase *zoneBuilder, QUndoCommand *parent = 0); + virtual ~UnloadLandscapeCommand(); + + virtual void undo(); + virtual void redo(); +private: + + Path m_path; + int m_id; + QString m_fileName; + PrimitivesTreeModel *const m_model; + LandscapeEditor::ZoneBuilderBase *const m_zoneBuilder; +}; + +/** +@class CreateRootPrimitiveCommand +@brief +@details +*/ class CreateRootPrimitiveCommand: public QUndoCommand { public: @@ -112,7 +140,7 @@ private: }; /** -@class LoadPrimitiveCommand +@class LoadRootPrimitiveCommand @brief @details */ @@ -136,7 +164,32 @@ private: }; /** -@class AddPrimitiveCommand +@class UnloadRootPrimitiveCommand +@brief +@details +*/ +class UnloadRootPrimitiveCommand: public QUndoCommand +{ +public: + UnloadRootPrimitiveCommand(const QModelIndex &index, WorldEditorScene *scene, + PrimitivesTreeModel *model, QTreeView *view, + QUndoCommand *parent = 0); + virtual ~UnloadRootPrimitiveCommand(); + + virtual void undo(); + virtual void redo(); +private: + + Path m_path; + QString m_fileName; + NLLIGO::CPrimitives *m_primitives; + WorldEditorScene *const m_scene; + PrimitivesTreeModel *const m_model; + QTreeView *m_view; +}; + +/** +@class AddPrimitiveByClassCommand @brief @details */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp index 967f6651d..944372735 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp @@ -67,6 +67,8 @@ AbstractWorldItem *WorldEditorScene::addWorldItemPoint(const QPointF &point, con { WorldItemPoint *item = new WorldItemPoint(point, angle, radius, showArrow); addItem(item); + + m_worldItems.push_back(item); return item; } @@ -74,6 +76,8 @@ AbstractWorldItem *WorldEditorScene::addWorldItemPath(const QPolygonF &polyline, { WorldItemPath *item = new WorldItemPath(polyline); addItem(item); + + m_worldItems.push_back(item); return item; } @@ -81,6 +85,8 @@ AbstractWorldItem *WorldEditorScene::addWorldItemZone(const QPolygonF &polygon) { WorldItemZone *item = new WorldItemZone(polygon); addItem(item); + + m_worldItems.push_back(item); return item; } @@ -90,6 +96,10 @@ void WorldEditorScene::removeWorldItem(QGraphicsItem *item) m_selectedItems.clear(); m_editedSelectedItems = false; m_firstSelection = false; + + // TODO + AbstractWorldItem *worldItem = qgraphicsitem_cast(item); + m_worldItems.removeOne(worldItem); delete item; } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h index c9da223a7..e981a703e 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h @@ -34,8 +34,8 @@ class AbstractWorldItem; /* @class WorldEditorScene -@brief -@details +@brief The WorldEditorScene provides a surface for managing a large number of 2D world items(point/path/zone). +@details WorldEditorScene also provides 'selections model' functionality, which differs from standart selection model. */ class WORLD_EDITOR_EXPORT WorldEditorScene : public LandscapeEditor::LandscapeSceneBase { @@ -56,22 +56,38 @@ public: QUndoStack *undoStack, QObject *parent = 0); virtual ~WorldEditorScene(); + /// Create WorldItemPoint and add in scene. AbstractWorldItem *addWorldItemPoint(const QPointF &point, const qreal angle, const qreal radius, bool showArrow); + + /// Create WorldItemPath and add in scene. AbstractWorldItem *addWorldItemPath(const QPolygonF &polyline, bool showArrow); + + /// Create WorldItemZone and add in scene. AbstractWorldItem *addWorldItemZone(const QPolygonF &polygon); + + /// Remove a world item from the scene. void removeWorldItem(QGraphicsItem *item); + /// Set current mode editing(select/move/rotate/scale/turn), above world items. void setModeEdit(WorldEditorScene::ModeEdit mode); + WorldEditorScene::ModeEdit editMode() const; + /// @return true if edit points mode is enabled, else false. bool isEnabledEditPoints() const; Q_SIGNALS: + /// This signal is emitted by WorldEditorScene when the selections changes. + /// The @selected value contains a list of all selected items. void updateSelectedItems(const QList &selected); public Q_SLOTS: + /// Enable/disable edit points mode (user can change shape of WorldItemZone and WorldItemPath) + /// void setEnabledEditPoints(bool enabled); + + /// Update of selections void updateSelection(const QList &selected, const QList &deselected); protected: @@ -102,6 +118,7 @@ private: qreal m_firstPickX, m_firstPickY, m_angle; QList m_selectedItems; QList m_selectedPoints; + QList m_worldItems; QList m_polygons; bool m_editedSelectedItems, m_firstSelection; uint m_lastPickedPrimitive; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h index 7268b6d03..9136712c5 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h @@ -53,8 +53,8 @@ const int EDGE_POINT_LAYER = 201; const int SIZE_ARROW = 20; /* -@class WorldItemPoint -@brief +@class AbstractWorldItem +@brief Abstract class for graphics item @details */ class AbstractWorldItem: public QGraphicsItem @@ -65,13 +65,21 @@ public: enum { Type = QGraphicsItem::UserType + 1 }; + /// Rotate item around @pivot point on &deltaAngle (deg). virtual void rotateOn(const QPointF &pivot, const qreal deltaAngle) {}; + + /// Scales item relatively @pivot point // TODO: add modes: IgnoreAspectRatio, KeepAspectRatio virtual void scaleOn(const QPointF &pivot, const QPointF &factor) {}; + + /// Rotate arrow on angle (deg). (only for WorldItemPoint) virtual void turnOn(const qreal angle) {}; virtual void radiusOn(const qreal radius) {}; + /// Change color virtual void setColor(const QColor &color) = 0; + + /// Enable/disable the mode edit shape (only for WorldItemPath and WorldItemPath) virtual void setEnabledSubPoints(bool enabled) = 0; virtual void moveSubPoint(WorldItemSubPoint *subPoint) {} @@ -103,7 +111,8 @@ protected: /* @class WorldItemPoint -@brief +@brief WorldItemPoint class provides a dot item with arrow and circle(@radius) +that you can add to a WorldEditorScene. @details */ class WorldItemPoint: public AbstractWorldItem @@ -148,7 +157,7 @@ private: /* @class WorldItemPath -@brief +@brief WorldItemPath class provides a polyline item that you can add to a WorldEditorScene. @details */ class WorldItemPath: public AbstractWorldItem @@ -188,7 +197,7 @@ private: /* @class WorldItemZone -@brief +@brief The WorldItemZone class provides a polygon item that you can add to a WorldEditorScene. @details */ class WorldItemZone: public AbstractWorldItem diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp index ba5543776..b2691fba3 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp @@ -165,6 +165,9 @@ void WorldEditorWindow::open() void WorldEditorWindow::loadWorldEditFile(const QString &fileName) { + if (m_primitivesModel->isWorldEditNodeLoaded()) + return; + Utils::WorldEditList worldEditList; if (!Utils::loadWorldEditFile(fileName.toStdString(), worldEditList)) { From 0415894b572b4937110013ef562785017dfc9d8b Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Tue, 23 Aug 2011 18:17:08 +0300 Subject: [PATCH 68/89] GSOC FINAL --HG-- branch : gsoc2011-worldeditorqt --- .../src/plugins/landscape_editor/landscape_actions.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h index a21bece5d..61abc4435 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h @@ -35,7 +35,7 @@ namespace LandscapeEditor /** @class OpenLandscapeCommand @brief -@details +@details */ class OpenLandscapeCommand: public QUndoCommand { @@ -53,7 +53,7 @@ private: /** @class NewLandscapeCommand @brief -@details +@details */ class NewLandscapeCommand: public QUndoCommand { @@ -69,7 +69,7 @@ private: /** @class LigoTileCommand @brief -@details +@details */ class LigoTileCommand: public QUndoCommand { @@ -93,7 +93,7 @@ private: /** @class UndoScanRegionCommand @brief -@details +@details */ class UndoScanRegionCommand: public QUndoCommand { @@ -117,7 +117,7 @@ private: /** @class LigoResizeCommand @brief -@details +@details */ class LigoResizeCommand: public QUndoCommand { From 4a13d9d848e7fd42eb10e4ef205b89667810b91f Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Mon, 26 Sep 2011 02:53:15 +0300 Subject: [PATCH 69/89] Changed: #1193 Updated landscape editor and world editor plugins with latest API changes to OVQT plugin system. Added the plugin-spec files for each plugin. --HG-- branch : gsoc2011-worldeditorqt --- .../landscape_editor_plugin.cpp | 27 ------------------- .../landscape_editor_plugin.h | 7 ----- .../landscape_editor_window.cpp | 6 ++--- .../ovqt_plugin_landscape_editor.xml | 10 +++++++ .../world_editor/ovqt_plugin_world_editor.xml | 11 ++++++++ .../world_editor/world_editor_actions.cpp | 22 +++++++-------- .../world_editor/world_editor_plugin.cpp | 27 ------------------- .../world_editor/world_editor_plugin.h | 7 ----- .../world_editor/world_editor_window.cpp | 6 ++--- 9 files changed, 38 insertions(+), 85 deletions(-) create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/ovqt_plugin_landscape_editor.xml create mode 100644 code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/ovqt_plugin_world_editor.xml diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_plugin.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_plugin.cpp index e7665b42f..bbd285adc 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_plugin.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_plugin.cpp @@ -67,33 +67,6 @@ void LandscapeEditorPlugin::setNelContext(NLMISC::INelContext *nelContext) m_libContext = new NLMISC::CLibraryContext(*nelContext); } -QString LandscapeEditorPlugin::name() const -{ - return tr("LandscapeEditor"); -} - -QString LandscapeEditorPlugin::version() const -{ - return "0.8"; -} - -QString LandscapeEditorPlugin::vendor() const -{ - return "GSoC2011_dnk-88"; -} - -QString LandscapeEditorPlugin::description() const -{ - return "Landscape editor ovqt plugin."; -} - -QStringList LandscapeEditorPlugin::dependencies() const -{ - QStringList list; - list.append(Core::Constants::OVQT_CORE_PLUGIN); - return list; -} - void LandscapeEditorPlugin::addAutoReleasedObject(QObject *obj) { m_plugMan->addObject(obj); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_plugin.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_plugin.h index 4515da8be..145972e29 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_plugin.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_plugin.h @@ -54,15 +54,8 @@ public: 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: diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp index 69b27c660..6b4377a37 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp @@ -24,7 +24,7 @@ #include "snapshot_dialog.h" #include "../core/icore.h" -#include "../core/imenu_manager.h" +#include "../core/menu_manager.h" #include "../core/core_constants.h" // NeL includes @@ -348,12 +348,12 @@ void LandscapeEditorWindow::updateStatusBar() void LandscapeEditorWindow::createMenus() { - Core::IMenuManager *menuManager = Core::ICore::instance()->menuManager(); + Core::MenuManager *menuManager = Core::ICore::instance()->menuManager(); } void LandscapeEditorWindow::createToolBars() { - Core::IMenuManager *menuManager = Core::ICore::instance()->menuManager(); + Core::MenuManager *menuManager = Core::ICore::instance()->menuManager(); //QAction *action = menuManager->action(Core::Constants::NEW); //m_ui.fileToolBar->addAction(action); //action = menuManager->action(Core::Constants::SAVE); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/ovqt_plugin_landscape_editor.xml b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/ovqt_plugin_landscape_editor.xml new file mode 100644 index 000000000..ab71b7044 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/ovqt_plugin_landscape_editor.xml @@ -0,0 +1,10 @@ + + ovqt_plugin_landscape_editor + LandscapeEditor + 0.8 + GSoC2011_dnk-88 + Landscape editor ovqt plugin. + + + + \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/ovqt_plugin_world_editor.xml b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/ovqt_plugin_world_editor.xml new file mode 100644 index 000000000..7a37eaf56 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/ovqt_plugin_world_editor.xml @@ -0,0 +1,11 @@ + + ovqt_plugin_world_editor + WorldEditor + 0.6 + GSoC2011_dnk-88 + Landscape editor ovqt plugin. + + + + + \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp index 1e27c9f12..7e78cdaf5 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp @@ -158,20 +158,20 @@ void addNewGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *mode primitive->getPropertyByName ("Color", color); item->setColor(QColor(color.R, color.G, color.B)); - } - QVariant variantNode; - variantNode.setValue(node); - item->setData(Constants::WORLD_EDITOR_NODE, variantNode); + QVariant variantNode; + variantNode.setValue(node); + item->setData(Constants::WORLD_EDITOR_NODE, variantNode); - QVariant graphicsData; - graphicsData.setValue(item); - node->setData(Constants::GRAPHICS_DATA_QT4_2D, graphicsData); + QVariant graphicsData; + graphicsData.setValue(item); + node->setData(Constants::GRAPHICS_DATA_QT4_2D, graphicsData); - QVariant persistenVariant; - QPersistentModelIndex *persistentIndex = new QPersistentModelIndex(primIndex); - persistenVariant.setValue(persistentIndex); - item->setData(Constants::NODE_PERISTENT_INDEX, persistenVariant); + QVariant persistenVariant; + QPersistentModelIndex *persistentIndex = new QPersistentModelIndex(primIndex); + persistenVariant.setValue(persistentIndex); + item->setData(Constants::NODE_PERISTENT_INDEX, persistenVariant); + } } int count = model->rowCount(primIndex); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_plugin.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_plugin.cpp index 23b51e9e3..aa995777a 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_plugin.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_plugin.cpp @@ -103,33 +103,6 @@ void WorldEditorPlugin::setNelContext(NLMISC::INelContext *nelContext) m_libContext = new NLMISC::CLibraryContext(*nelContext); } -QString WorldEditorPlugin::name() const -{ - return tr("WorldEditor"); -} - -QString WorldEditorPlugin::version() const -{ - return "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); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_plugin.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_plugin.h index 11e2c7871..4a107d11b 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_plugin.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_plugin.h @@ -56,15 +56,8 @@ public: 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: diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp index b2691fba3..f1b8b17f1 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp @@ -26,7 +26,7 @@ // Core #include "../core/icore.h" -#include "../core/imenu_manager.h" +#include "../core/menu_manager.h" #include "../core/core_constants.h" // Lanscape Editor plugin @@ -347,12 +347,12 @@ void WorldEditorWindow::hideEvent(QHideEvent *hideEvent) void WorldEditorWindow::createMenus() { - Core::IMenuManager *menuManager = Core::ICore::instance()->menuManager(); + Core::MenuManager *menuManager = Core::ICore::instance()->menuManager(); } void WorldEditorWindow::createToolBars() { - Core::IMenuManager *menuManager = Core::ICore::instance()->menuManager(); + Core::MenuManager *menuManager = Core::ICore::instance()->menuManager(); //QAction *action = menuManager->action(Core::Constants::NEW); //m_ui.fileToolBar->addAction(action); From cae892cda2cb9a6c9e9451aff5d033a15519c350 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Mon, 3 Oct 2011 00:40:25 +0300 Subject: [PATCH 70/89] Changed: #1301 Polished code. --HG-- branch : gsoc2011-worldeditorqt --- .../landscape_editor/builder_zone_base.h | 2 +- .../landscape_editor/builder_zone_region.cpp | 70 +++++++------------ .../landscape_editor/builder_zone_region.h | 23 +++--- .../landscape_editor/landscape_actions.cpp | 35 ---------- .../landscape_editor/landscape_actions.h | 34 --------- .../landscape_editor_plugin.h | 7 +- .../landscape_editor_window.cpp | 2 +- .../landscape_editor_window.h | 2 +- .../landscape_editor/landscape_scene.cpp | 20 ------ .../landscape_editor/landscape_view.cpp | 10 --- .../plugins/landscape_editor/landscape_view.h | 2 +- .../landscape_editor/list_zones_widget.h | 2 +- .../landscape_editor/pixmap_database.cpp | 2 +- .../landscape_editor/pixmap_database.h | 2 +- .../landscape_editor/snapshot_dialog.h | 2 +- .../landscape_editor/zone_region_editor.cpp | 12 ---- .../plugins/world_editor/primitive_item.cpp | 14 ++-- .../src/plugins/world_editor/primitive_item.h | 5 +- .../plugins/world_editor/primitives_model.cpp | 4 ++ .../plugins/world_editor/primitives_model.h | 6 +- .../plugins/world_editor/primitives_view.cpp | 44 +++--------- .../plugins/world_editor/primitives_view.h | 2 +- .../world_editor/property_editor_widget.h | 2 +- .../world_editor/world_editor_actions.cpp | 26 ------- .../world_editor/world_editor_constants.h | 5 +- .../world_editor/world_editor_misc.cpp | 59 ++-------------- .../plugins/world_editor/world_editor_misc.h | 1 - .../world_editor/world_editor_plugin.h | 5 -- .../world_editor/world_editor_scene.cpp | 40 ++++------- .../plugins/world_editor/world_editor_scene.h | 5 +- .../world_editor/world_editor_settings_page.h | 2 +- .../world_editor/world_editor_window.cpp | 10 ++- .../world_editor/world_editor_window.h | 2 +- 33 files changed, 110 insertions(+), 349 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_base.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_base.h index 8ea7f79a3..a8637d463 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_base.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_base.h @@ -75,7 +75,7 @@ PixmapDatabase contains the graphics for the zones class LANDSCAPE_EDITOR_EXPORT ZoneBuilderBase { public: - ZoneBuilderBase(LandscapeSceneBase *landscapeScene); + explicit ZoneBuilderBase(LandscapeSceneBase *landscapeScene); virtual ~ZoneBuilderBase(); /// Init zoneBank and init zone pixmap database diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.cpp index 3f787e6b0..e84a81f57 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.cpp @@ -230,34 +230,18 @@ void BuilderZoneRegion::add(sint32 x, sint32 y, uint8 rot, uint8 flip, NLLIGO::C } // Delete all around all material that are not from the same as us - const std::string &curMat = zoneBankElement->getCategory ("material"); + const std::string &curMat = zoneBankElement->getCategory("material"); if (curMat != STRING_NO_CAT_TYPE) { // This element is a valid material // Place the piece - const std::string &eltName = zoneBankElement->getName (); - for (j = 0; j < sMask.h; ++j) - for (i = 0; i < sMask.w; ++i) - if (sMask.Tab[i + j * sMask.w]) - { - set(x + i, y + j, sPosX.Tab[i + j * sPosX.w], sPosY.Tab[i + j * sPosY.w], eltName); - setRot(x + i, y + j, rot); - setFlip(x + i, y + j, flip); - } + const std::string &eltName = zoneBankElement->getName(); + placePiece(x, y, rot, flip, sMask, sPosX, sPosY, eltName); // Put all transitions between different materials putTransitions (x, y, sMask, curMat, &tUpdate); - - // Place the piece - for (j = 0; j < sMask.h; ++j) - for (i = 0; i < sMask.w; ++i) - if (sMask.Tab[i + j * sMask.w]) - { - set(x + i, y + j, sPosX.Tab[i + j * sPosX.w], sPosY.Tab[i + j * sPosY.w], eltName); - setRot(x + i, y + j, rot); - setFlip(x + i, y + j, flip); - } + placePiece(x, y, rot, flip, sMask, sPosX, sPosY, eltName); } } @@ -449,21 +433,14 @@ bool BuilderZoneRegion::addNotPropagate (sint32 x, sint32 y, uint8 rot, uint8 fl del(x + i, y + j, true, &tUpdate); } - const std::string &curMat = zoneBankElement->getCategory ("material"); + const std::string &curMat = zoneBankElement->getCategory("material"); if (curMat != STRING_NO_CAT_TYPE) { // This element is a valid material // Place the piece - const std::string &EltName = zoneBankElement->getName (); - for (j = 0; j < sMask.h; ++j) - for (i = 0; i < sMask.w; ++i) - if (sMask.Tab[i + j * sMask.w]) - { - set (x + i, y + j, sPosX.Tab[i + j * sPosX.w], sPosY.Tab[i + j * sPosY.w], EltName); - setRot (x + i, y + j, rot); - setFlip (x + i, y + j, flip); - } + const std::string &eltName = zoneBankElement->getName(); + placePiece(x, y, rot, flip, sMask, sPosX, sPosY, eltName); } return true; @@ -803,11 +780,10 @@ void BuilderZoneRegion::addTransition (sint32 x, sint32 y, uint8 rot, uint8 flip } } -void BuilderZoneRegion::addToUpdateAndCreate(BuilderZoneRegion *builderZoneRegion, sint32 sharePos, sint32 x, sint32 y, const std::string &newMat, void *pInt1, void *pInt2) +void BuilderZoneRegion::addToUpdateAndCreate(BuilderZoneRegion *builderZoneRegion, sint32 sharePos, sint32 x, sint32 y, + const std::string &newMat, ToUpdate *ptCreate, ToUpdate *ptUpdate) { const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->ligoZoneRegion(); - ToUpdate *ptCreate = reinterpret_cast(pInt1); - ToUpdate *ptUpdate = reinterpret_cast(pInt2); sint32 stride = (1 + zoneRegion.getMaxX() - zoneRegion.getMinX()); ZonePosition zonePos; @@ -828,11 +804,10 @@ void BuilderZoneRegion::addToUpdateAndCreate(BuilderZoneRegion *builderZoneRegio } void BuilderZoneRegion::putTransitions (sint32 inX, sint32 inY, const NLLIGO::SPiece &mask, const std::string &matName, - void *pInternal) + ToUpdate *ptUpdate) { const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->ligoZoneRegion(); ToUpdate tCreate; // Transition to create - ToUpdate *ptUpdate = reinterpret_cast(pInternal); // Transition to update sint32 i, j, k, l, m; sint32 x = inX, y = inY; @@ -883,10 +858,8 @@ void BuilderZoneRegion::putTransitions (sint32 inX, sint32 inY, const NLLIGO::SP if ( (corner < 4) && (m != 0) ) { // The material can't be paused - dataZoneTemp.sharingMatNames[0] = STRING_UNUSED; - dataZoneTemp.sharingMatNames[1] = STRING_UNUSED; - dataZoneTemp.sharingMatNames[2] = STRING_UNUSED; - dataZoneTemp.sharingMatNames[3] = STRING_UNUSED; + for (int t = 0; i < 4; ++t) + dataZoneTemp.sharingMatNames[t] = STRING_UNUSED; // Don't propagate any more } @@ -1659,16 +1632,13 @@ void BuilderZoneRegion::tryPath(uint32 posA, uint32 posB, std::vector &p } } -void BuilderZoneRegion::del(sint32 x, sint32 y, bool transition, void *pInternal) +void BuilderZoneRegion::del(sint32 x, sint32 y, bool transition, ToUpdate *pUpdate) { const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->ligoZoneRegion(); if (!m_zoneBuilder->getZoneMask(x, y)) return; const std::string &nameZone = zoneRegion.getName(x, y); - - ToUpdate *pUpdate = reinterpret_cast(pInternal); - NLLIGO::CZoneBankElement *zoneBankElement = m_zoneBuilder->getZoneBank().getElementByZoneName(nameZone); if (zoneBankElement != NULL) { @@ -2108,4 +2078,18 @@ void BuilderZoneRegion::resize (sint32 newMinX, sint32 newMaxX, sint32 newMinY, } } +void BuilderZoneRegion::placePiece(sint32 x, sint32 y, uint8 rot, uint8 flip, + NLLIGO::SPiece &sMask, NLLIGO::SPiece &sPosX, NLLIGO::SPiece &sPosY, + const std::string &eltName) +{ + for (int j = 0; j < sMask.h; ++j) + for (int i = 0; i < sMask.w; ++i) + if (sMask.Tab[i + j * sMask.w]) + { + set(x + i, y + j, sPosX.Tab[i + j * sPosX.w], sPosY.Tab[i + j * sPosY.w], eltName); + setRot(x + i, y + j, rot); + setFlip(x + i, y + j, flip); + } +} + } /* namespace LandscapeEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.h index 6de45da50..2170c67b9 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.h @@ -33,13 +33,15 @@ namespace LandscapeEditor { class ZoneBuilder; +class ToUpdate; -// CZoneRegion contains informations about the zones painted +// CZoneRegion contains informations about the zones painted. +// (Legacy class from old world editor. It needs to refactoring!) class BuilderZoneRegion { public: - BuilderZoneRegion(uint regionId); + explicit BuilderZoneRegion(uint regionId); // New interface bool init(ZoneBuilder *zoneBuilder); @@ -51,7 +53,7 @@ public: /// 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 del(sint32 x, sint32 y, bool transition = false, ToUpdate *pUpdate = 0); void move(sint32 x, sint32 y); uint32 countZones(); void reduceMin(); @@ -62,28 +64,33 @@ private: // An element of the graph struct SMatNode { - std::string Name; + std::string Name; // Position in the tree (vector of nodes) std::vector 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 addToUpdateAndCreate(BuilderZoneRegion *builderZoneRegion, sint32 sharePos, sint32 x, sint32 y, + const std::string &newMat, ToUpdate *ptCreate, ToUpdate *ptUpdate); - void putTransitions(sint32 x, sint32 y, const NLLIGO::SPiece &mask, const std::string &matName, void *pInternal); - void updateTrans(sint32 x, sint32 y, NLLIGO::CZoneBankElement *zoneBankElement = NULL); + void putTransitions(sint32 x, sint32 y, const NLLIGO::SPiece &mask, const std::string &matName, ToUpdate *ptUpdate); + void updateTrans(sint32 x, sint32 y, NLLIGO::CZoneBankElement *zoneBankElement = 0); std::string getNextMatInTree(const std::string &matA, const std::string &matB); /// Find the fastest way between posA and posB in the MatTree (Dijkstra) void tryPath(uint32 posA, uint32 posB, std::vector &path); - void set(sint32 x, sint32 y, sint32 posX, sint32 posY, const std::string &zoneName, bool transition=false); + void set(sint32 x, sint32 y, sint32 posX, sint32 posY, const std::string &zoneName, bool transition = false); void setRot(sint32 x, sint32 y, uint8 rot); void setFlip(sint32 x, sint32 y, uint8 flip); void resize(sint32 newMinX, sint32 newMaxX, sint32 newMinY, sint32 newMaxY); + void placePiece(sint32 x, sint32 y, uint8 rot, uint8 flip, + NLLIGO::SPiece &sMask, NLLIGO::SPiece &sPosX, NLLIGO::SPiece &sPosY, + const std::string &eltName); + uint m_regionId; // To use the global mask diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp index dc8b003c7..e5b3ad4d4 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.cpp @@ -27,41 +27,6 @@ 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) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h index 61abc4435..c976360fa 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_actions.h @@ -32,40 +32,6 @@ namespace LandscapeEditor { -/** -@class OpenLandscapeCommand -@brief -@details -*/ -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 -@brief -@details -*/ -class NewLandscapeCommand: public QUndoCommand -{ -public: - NewLandscapeCommand(QUndoCommand *parent = 0); - virtual ~NewLandscapeCommand(); - - virtual void undo(); - virtual void redo(); -private: -}; - /** @class LigoTileCommand @brief diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_plugin.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_plugin.h index 145972e29..a01867894 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_plugin.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_plugin.h @@ -34,11 +34,6 @@ namespace NLMISC class CLibraryContext; } -namespace ExtensionSystem -{ -class IPluginSpec; -} - namespace LandscapeEditor { class LandscapeEditorWindow; @@ -70,7 +65,7 @@ class LandscapeEditorContext: public Core::IContext { Q_OBJECT public: - LandscapeEditorContext(QObject *parent = 0); + explicit LandscapeEditorContext(QObject *parent = 0); virtual ~LandscapeEditorContext() {} virtual QString id() const diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp index 6b4377a37..22598c555 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp @@ -262,7 +262,7 @@ int LandscapeEditorWindow::createLandscape(const QString &fileName) if (id == -1) { - QMessageBox::critical(this, "Landscape Editor", "Cannot add this zone because it overlaps existing ones"); + QMessageBox::critical(this, "Landscape Editor", tr("Cannot add this zone because it overlaps existing ones")); return -1; } ZoneRegionObject *zoneRegion = m_zoneBuilder->zoneRegion(id); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h index 92745365b..6047a9e5e 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.h @@ -37,7 +37,7 @@ class LandscapeEditorWindow: public QMainWindow Q_OBJECT public: - LandscapeEditorWindow(QWidget *parent = 0); + explicit LandscapeEditorWindow(QWidget *parent = 0); ~LandscapeEditorWindow(); QUndoStack *undoStack() const; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp index bb2605b80..0018b4a53 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.cpp @@ -397,26 +397,6 @@ 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) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp index 10e1348df..87a459511 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp @@ -185,23 +185,14 @@ void LandscapeView::setCenter(const QPointF ¢erPoint) //We need to clamp the center. The centerPoint is too large if (centerPoint.x() > bounds.x() + bounds.width()) - { m_currentCenterPoint.setX(bounds.x() + bounds.width()); - } else if(centerPoint.x() < bounds.x()) - { m_currentCenterPoint.setX(bounds.x()); - } if(centerPoint.y() > bounds.y() + bounds.height()) - { m_currentCenterPoint.setY(bounds.y() + bounds.height()); - } else if(centerPoint.y() < bounds.y()) - { m_currentCenterPoint.setY(bounds.y()); - } - } } @@ -230,7 +221,6 @@ void LandscapeView::drawForeground(QPainter *painter, const QRectF &rect) if (transform().m11() > m_maxViewText) { painter->setPen(QPen(Qt::white, 0.5, Qt::SolidLine)); - //painter->setFont(QFont("Helvetica [Cronyx]", 12)); drawZoneNames(painter, rect); } } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h index 462e6ecfb..158edfaa9 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h @@ -37,7 +37,7 @@ class LANDSCAPE_EDITOR_EXPORT LandscapeView: public QGraphicsView Q_OBJECT public: - LandscapeView(QWidget *parent = 0); + explicit LandscapeView(QWidget *parent = 0); virtual ~LandscapeView(); //Set the current centerpoint in the diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h index 091c33908..f33eda706 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_widget.h @@ -39,7 +39,7 @@ class ListZonesWidget: public QWidget Q_OBJECT public: - ListZonesWidget(QWidget *parent = 0); + explicit ListZonesWidget(QWidget *parent = 0); ~ListZonesWidget(); void updateUi(); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.cpp index 83e581ff3..0156f5a53 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.cpp @@ -64,7 +64,7 @@ bool PixmapDatabase::loadPixmaps(const QString &zonePath, NLLIGO::CZoneBank &zon zoneBank.getCategoryValues ("zone", listNames); if (displayProgress) { - progressDialog = new QProgressDialog("Loading ligo zones.", "Cancel", 0, listNames.size()); + progressDialog = new QProgressDialog(QObject::tr("Loading ligo zones."), QObject::tr("Cancel"), 0, listNames.size()); progressDialog->show(); } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.h index 15b26e474..282872343 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.h @@ -39,7 +39,7 @@ namespace LandscapeEditor class LANDSCAPE_EDITOR_EXPORT PixmapDatabase { public: - PixmapDatabase(int textureSize = 256); + explicit PixmapDatabase(int textureSize = 256); ~PixmapDatabase(); /// Load all images(png) from zonePath, list images gets from zoneBank diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/snapshot_dialog.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/snapshot_dialog.h index 34db0e4a2..07844ce31 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/snapshot_dialog.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/snapshot_dialog.h @@ -30,7 +30,7 @@ class SnapshotDialog: public QDialog Q_OBJECT public: - SnapshotDialog(QWidget *parent = 0); + explicit SnapshotDialog(QWidget *parent = 0); ~SnapshotDialog(); bool isCustomSize() const; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.cpp index a9699acee..874c5d533 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/zone_region_editor.cpp @@ -118,12 +118,6 @@ void ZoneRegionObject::setFileName(const std::string &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); @@ -141,12 +135,6 @@ void ZoneRegionObject::ligoData(LigoData &data, const sint32 x, const sint32 y) 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); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.cpp index 658231b2c..c0d799401 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.cpp @@ -215,20 +215,18 @@ PrimitiveNode::PrimitiveNode(NLLIGO::IPrimitive *primitive) m_primitive->getPropertyByName("class", className); // Set Icon - QString nameIcon = QString("./old_ico/%1.ico").arg(className.c_str()); + QString nameIcon = QString("%1/%2.ico").arg(Constants::PATH_TO_OLD_ICONS).arg(className.c_str()); QIcon icon(nameIcon); if (!QFile::exists(nameIcon)) { if (primitive->getParent() == NULL) - icon = QIcon("./old_ico/root.ico"); + icon = QIcon(Constants::ICON_ROOT_PRIMITIVE); else if (primitive->getNumChildren() == 0) - icon = QIcon("./old_ico/property.ico"); + icon = QIcon(Constants::ICON_PROPERTY); else - icon = QIcon("./old_ico/folder_h.ico"); + icon = QIcon(Constants::ICON_FOLDER); } setData(Qt::DecorationRole, icon); - - //setData(3, QString(className.c_str())); } PrimitiveNode::~PrimitiveNode() @@ -242,7 +240,7 @@ NLLIGO::IPrimitive *PrimitiveNode::primitive() const const NLLIGO::CPrimitiveClass *PrimitiveNode::primitiveClass() const { - return NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig->getPrimitiveClass(*m_primitive); + return Utils::ligoConfig()->getPrimitiveClass(*m_primitive); } RootPrimitiveNode *PrimitiveNode::rootPrimitiveNode() @@ -250,7 +248,7 @@ RootPrimitiveNode *PrimitiveNode::rootPrimitiveNode() Node *node = this; while (node && (node->type() != Node::RootPrimitiveNodeType)) node = node->parent(); - return (RootPrimitiveNode *)node; + return static_cast(node); } Node::NodeType PrimitiveNode::type() const diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h index f95eff0c0..7ebf4437f 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h @@ -30,10 +30,7 @@ namespace WorldEditor { -class WorldEditNode; class RootPrimitiveNode; -class LandscapeNode; -class PrimitiveNode; /* @class Node @@ -150,7 +147,7 @@ private: class PrimitiveNode: public Node { public: - PrimitiveNode(NLLIGO::IPrimitive *primitive); + explicit PrimitiveNode(NLLIGO::IPrimitive *primitive); virtual ~PrimitiveNode(); NLLIGO::IPrimitive *primitive() const; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.cpp index 46436b699..78313624e 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.cpp @@ -183,6 +183,10 @@ Node *PrimitivesTreeModel::pathToNode(const Path &path) void PrimitivesTreeModel::createWorldEditNode(const QString &fileName) { + // World edit node already is created, if yes is showing error message box + if (m_worldEditNode != 0) + nlerror("World edit node already is created."); + beginResetModel(); m_worldEditNode = new WorldEditNode(fileName); m_rootNode->appendChildNode(m_worldEditNode); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.h index d1a883106..031317d0c 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_model.h @@ -39,7 +39,8 @@ const int AtTheEnd = -1; typedef QPair 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 +@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. +It is used for undo/redo commands. */ typedef QList Path; @@ -53,7 +54,7 @@ class PrimitivesTreeModel : public QAbstractItemModel Q_OBJECT public: - PrimitivesTreeModel(QObject *parent = 0); + explicit PrimitivesTreeModel(QObject *parent = 0); ~PrimitivesTreeModel(); QVariant data(const QModelIndex &index, int role) const; @@ -92,7 +93,6 @@ public: private: void createChildNodes(NLLIGO::IPrimitive *primitive, int pos, const QModelIndex &parent); - void removeChildNodes(Node *node, const QModelIndex &parent); Node *m_rootNode; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.cpp index 6395720c5..e27e824b4 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.cpp @@ -61,7 +61,7 @@ PrimitivesView::PrimitivesView(QWidget *parent) 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_loadPrimitiveAction->setIcon(QIcon(Constants::ICON_ROOT_PRIMITIVE)); m_newPrimitiveAction = new QAction("New primitive", this); @@ -132,7 +132,7 @@ void PrimitivesView::loadRootPrimitive() if (!fileNames.isEmpty()) { if (fileNames.count() > 1) - m_undoStack->beginMacro("Load primitive files"); + m_undoStack->beginMacro(tr("Load primitive files")); Q_FOREACH(QString fileName, fileNames) { @@ -160,7 +160,7 @@ void PrimitivesView::loadLandscape() if (!fileNames.isEmpty()) { if (fileNames.count() > 1) - m_undoStack->beginMacro("Load land files"); + m_undoStack->beginMacro(tr("Load land files")); Q_FOREACH(QString fileName, fileNames) { @@ -206,7 +206,7 @@ void PrimitivesView::save() if (node->data(Constants::PRIMITIVE_FILE_IS_CREATED).toBool()) { if (!NLLIGO::saveXmlPrimitiveFile(*node->primitives(), node->fileName().toStdString())) - QMessageBox::warning(this, "World Editor Qt", QString("Error writing output file: %1").arg(node->fileName())); + QMessageBox::warning(this, "World Editor Qt", tr("Error writing output file: %1").arg(node->fileName())); else node->setData(Constants::PRIMITIVE_IS_MODIFIED, false); } @@ -231,7 +231,7 @@ void PrimitivesView::saveAs() RootPrimitiveNode *node = static_cast(index.internalPointer()); if (!NLLIGO::saveXmlPrimitiveFile(*node->primitives(), fileName.toStdString())) - QMessageBox::warning(this, "World Editor Qt", QString("Error writing output file: %1").arg(fileName)); + QMessageBox::warning(this, "World Editor Qt", tr("Error writing output file: %1").arg(fileName)); else { node->setFileName(fileName); @@ -407,7 +407,7 @@ void PrimitivesView::fillMenu_Primitive(QMenu *menu, const QModelIndex &index) QSignalMapper *addSignalMapper = new QSignalMapper(menu); QSignalMapper *generateSignalMapper = new QSignalMapper(menu); - QSignalMapper *openSignalMapper = 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))); @@ -427,10 +427,10 @@ void PrimitivesView::fillMenu_Primitive(QMenu *menu, const QModelIndex &index) QString className = primClass->DynamicChildren[i].ClassName.c_str(); // Get icon - QIcon icon(QString("./old_ico/%1.ico").arg(className)); + QIcon icon(QString("%1/%2.ico").arg(Constants::PATH_TO_OLD_ICONS).arg(className)); // Create and add action in popur menu - QAction *action = menu->addAction(icon, QString("Add %1").arg(className)); + QAction *action = menu->addAction(icon, tr("Add %1").arg(className)); addSignalMapper->setMapping(action, i); connect(action, SIGNAL(triggered()), addSignalMapper, SLOT(map())); } @@ -448,35 +448,11 @@ void PrimitivesView::fillMenu_Primitive(QMenu *menu, const QModelIndex &index) QString childName = primClass->GeneratedChildren[i].ClassName.c_str(); // Create and add action in popur menu - QAction *action = menu->addAction(QString("Generate %1").arg(childName)); + QAction *action = menu->addAction(tr("Generate %1").arg(childName)); generateSignalMapper->setMapping(action, i); - connect(generateSignalMapper, SIGNAL(triggered()), addSignalMapper, SLOT(map())); + connect(action, SIGNAL(triggered()), generateSignalMapper, SLOT(map())); } } - /* - // What class is it ? - if (primClass) - { - // Look for files - std::vector 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 */ \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.h index 2b16bc714..8da877658 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitives_view.h @@ -53,7 +53,7 @@ class PrimitivesView : public QTreeView Q_OBJECT public: - PrimitivesView(QWidget *parent = 0); + explicit PrimitivesView(QWidget *parent = 0); ~PrimitivesView(); void setUndoStack(QUndoStack *undoStack); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.h index 18f72fadc..3ee73a293 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.h @@ -45,7 +45,7 @@ class PropertyEditorWidget: public QWidget Q_OBJECT public: - PropertyEditorWidget(QWidget *parent = 0); + explicit PropertyEditorWidget(QWidget *parent = 0); ~PropertyEditorWidget(); public Q_SLOTS: diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp index 7e78cdaf5..0f9d91ef2 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_actions.cpp @@ -103,13 +103,11 @@ void addNewGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *mode QPolygonF polygon; vec = primitive->getPrimVector(); int sizeVec = primitive->getNumVector(); - for (int i = 0; i < sizeVec; ++i) { polygon << QPointF(vec->x, -vec->y + cellSize); ++vec; } - item = scene->addWorldItemPath(polygon, showArrow); break; } @@ -118,7 +116,6 @@ void addNewGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *mode QPolygonF polygon; vec = primitive->getPrimVector(); int sizeVec = primitive->getNumVector(); - for (int i = 0; i < sizeVec; ++i) { polygon << QPointF(vec->x, cellSize - vec->y); @@ -133,30 +130,7 @@ void addNewGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *mode { // Get color from world_editor_classes.xml NLMISC::CRGBA color = Utils::ligoConfig()->getPrimitiveColor(*primitive); - - /* - // Configurations (from world_editor_primitive_configuration.xml) - const std::vector &configurations = Utils::ligoConfig()->getPrimitiveConfiguration(); - - // Look for the configuration - sint search = 0; - bool colorFound = false; - while ((search = theApp.getActiveConfiguration (*primitive, search)) != -1) - { - // Configuration activated ? - if (theApp.Configurations[search].Activated) - { - colorFound = true; - mainColor = configurations[search].Color; - break; - } - search++; - } - - // try to get the primitive color ? - //if (!colorFound)*/ primitive->getPropertyByName ("Color", color); - item->setColor(QColor(color.R, color.G, color.B)); QVariant variantNode; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_constants.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_constants.h index 0e27301d5..a75e2148b 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_constants.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_constants.h @@ -44,7 +44,10 @@ const char *const PRIMITIVE_CLASS_FILENAME = "WorldEditorPrimitiveClassFilename" //resources const char *const ICON_WORLD_EDITOR = ":/icons/ic_nel_world_editor.png"; - +const char *const ICON_ROOT_PRIMITIVE = "./old_ico/root.ico"; +const char *const ICON_PROPERTY = "./old_ico/property.ico"; +const char *const ICON_FOLDER = "./old_ico/folder_h.ico"; +const char *const PATH_TO_OLD_ICONS = "./old_ico"; } // namespace Constants } // namespace WorldEditor diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_misc.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_misc.cpp index 5b5b9540d..6db59f9e5 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_misc.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_misc.cpp @@ -1,6 +1,5 @@ // Object Viewer Qt - MMORPG Framework // Copyright (C) 2010 Winch Gate Property Limited -// Copyright (C) 2011 Dzmitry Kamiahin // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as @@ -99,7 +98,6 @@ bool loadWorldEditFile(const std::string &fileName, WorldEditList &worldEditList // Good header ? if (strcmp((const char *)(rootNode->name), "NEL_WORLD_EDITOR_PROJECT") == 0) { - // Read the version int version = -1; // Read the parameters @@ -112,10 +110,7 @@ bool loadWorldEditFile(const std::string &fileName, WorldEditList &worldEditList } if (version == -1) - { - // Error syntaxError(fileName.c_str(), rootNode, "No version node"); - } else { // Old format, @@ -213,9 +208,7 @@ bool loadWorldEditFile(const std::string &fileName, WorldEditList &worldEditList } } else - { nlerror("Can't open the file %s for reading.", fileName.c_str()); - } return result; } @@ -255,12 +248,10 @@ void initPrimitiveParameters(const NLLIGO::CPrimitiveClass &primClass, NLLIGO::I if (cp < primClass.Parameters.size()) type = primClass.Parameters[cp].Type; - // Name ? if (initParameters[p].Name == "name") type = NLLIGO::CPrimitiveClass::CParameter::String; - // Continue ? - if (cpStringArray[i] = NLMISC::toString(getUniqueId()); - } else - { str->StringArray[i] = ""; - } } primitive.addPropertyByName(parameter.Name.c_str(), str); } @@ -347,7 +330,7 @@ NLLIGO::IPrimitive *createPrimitive(const char *className, const char *primName, NLLIGO::IPrimitive *parent) { // Get the prim class - const NLLIGO::CPrimitiveClass *primClass = NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig->getPrimitiveClass(className); + const NLLIGO::CPrimitiveClass *primClass = ligoConfig()->getPrimitiveClass(className); if (primClass) { // Create the base primitive @@ -438,41 +421,18 @@ NLLIGO::IPrimitive *createPrimitive(const char *className, const char *primName, 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(primitive)->init(dialog.GetPathName ()); - //} - } - - // Continue ? if (primitive) { - // Auto init ? if (!primClass->AutoInit) { - // Make a vector of locator - //CDatabaseLocatorPointer locatorPtr; - //getLocator (locatorPtr, locator); - std::list locators; - //locators.push_back (const_cast (locatorPtr.Primitive)); - - // Yes, go - //CDialogProperties dialogProperty (locators, getMainFrame ()); - //dialogProperty.DoModal (); + // TODO } // 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); + const NLLIGO::CPrimitiveClass *primClass = ligoConfig()->getPrimitiveClass(*primitive); if (primClass) { for (size_t i = 0; i < primClass->Parameters.size(); ++i) @@ -491,17 +451,13 @@ NLLIGO::IPrimitive *createPrimitive(const char *className, const char *primName, } } - // Init primitive default values - primitive->initDefaultValues(*NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig); + primitive->initDefaultValues(*ligoConfig()); } - - // Done return primitive; } else - { nlerror("Unknown primitive class name : %s", className); - } + return 0; } @@ -521,11 +477,10 @@ void deletePrimitive(NLLIGO::IPrimitive *primitive) bool updateDefaultValues(NLLIGO::IPrimitive *primitive) { - // Modified bool modified = false; // Get the prim class - const NLLIGO::CPrimitiveClass *primClass = NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig->getPrimitiveClass(*primitive); + const NLLIGO::CPrimitiveClass *primClass = ligoConfig()->getPrimitiveClass(*primitive); nlassert(primClass); if (primClass) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_misc.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_misc.h index 4163ae2e0..d29b2553b 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_misc.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_misc.h @@ -1,6 +1,5 @@ // Object Viewer Qt - MMORPG Framework // Copyright (C) 2010 Winch Gate Property Limited -// Copyright (C) 2011 Dzmitry Kamiahin // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_plugin.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_plugin.h index 4a107d11b..686b87e14 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_plugin.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_plugin.h @@ -36,11 +36,6 @@ namespace NLMISC class CLibraryContext; } -namespace ExtensionSystem -{ -class IPluginSpec; -} - namespace WorldEditor { class WorldEditorWindow; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp index 944372735..f2103031c 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp @@ -45,17 +45,15 @@ WorldEditorScene::WorldEditorScene(int sizeCell, PrimitivesTreeModel *model, QUn // TODO: get params from settings setSceneRect(QRectF(-20 * 160, -20 * 160, 256 * 160, 256 * 160)); - m_pen1.setColor(QColor(50, 255, 155)); - m_pen1.setWidth(0); - - m_brush1.setColor(QColor(50, 255, 155, 80)); - m_brush1.setStyle(Qt::SolidPattern); - - m_pen2.setColor(QColor(100, 0, 255)); - m_pen2.setWidth(0); - - m_brush2.setColor(QColor(100, 0, 255, 80)); - m_brush2.setStyle(Qt::SolidPattern); + m_greenPen.setColor(QColor(50, 255, 155)); + m_greenPen.setWidth(0); + m_greenBrush.setColor(QColor(50, 255, 155, 80)); + m_greenBrush.setStyle(Qt::SolidPattern); + + m_purplePen.setColor(QColor(100, 0, 255)); + m_purplePen.setWidth(0); + m_purpleBrush.setColor(QColor(100, 0, 255, 80)); + m_purpleBrush.setStyle(Qt::SolidPattern); } WorldEditorScene::~WorldEditorScene() @@ -67,8 +65,6 @@ AbstractWorldItem *WorldEditorScene::addWorldItemPoint(const QPointF &point, con { WorldItemPoint *item = new WorldItemPoint(point, angle, radius, showArrow); addItem(item); - - m_worldItems.push_back(item); return item; } @@ -76,8 +72,6 @@ AbstractWorldItem *WorldEditorScene::addWorldItemPath(const QPolygonF &polyline, { WorldItemPath *item = new WorldItemPath(polyline); addItem(item); - - m_worldItems.push_back(item); return item; } @@ -85,8 +79,6 @@ AbstractWorldItem *WorldEditorScene::addWorldItemZone(const QPolygonF &polygon) { WorldItemZone *item = new WorldItemZone(polygon); addItem(item); - - m_worldItems.push_back(item); return item; } @@ -96,10 +88,6 @@ void WorldEditorScene::removeWorldItem(QGraphicsItem *item) m_selectedItems.clear(); m_editedSelectedItems = false; m_firstSelection = false; - - // TODO - AbstractWorldItem *worldItem = qgraphicsitem_cast(item); - m_worldItems.removeOne(worldItem); delete item; } @@ -174,18 +162,18 @@ void WorldEditorScene::drawForeground(QPainter *painter, const QRectF &rect) if ((m_selectionArea.left() != 0) && (m_selectionArea.right() != 0)) { + // Draw selection area if (m_selectionArea.left() < m_selectionArea.right()) { - painter->setPen(m_pen1); - painter->setBrush(m_brush1); + painter->setPen(m_greenPen); + painter->setBrush(m_greenBrush); } else { - painter->setPen(m_pen2); - painter->setBrush(m_brush2); + painter->setPen(m_purplePen); + painter->setBrush(m_purpleBrush); } painter->drawRect(m_selectionArea); - } } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h index e981a703e..833412410 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h @@ -110,15 +110,14 @@ private: void checkUndo(); - QPen m_pen1, m_pen2; - QBrush m_brush1, m_brush2; + QPen m_greenPen, m_purplePen; + QBrush m_greenBrush, m_purpleBrush; QPointF m_firstPick, m_scaleFactor, m_pivot; QRectF m_selectionArea; qreal m_firstPickX, m_firstPickY, m_angle; QList m_selectedItems; QList m_selectedPoints; - QList m_worldItems; QList m_polygons; bool m_editedSelectedItems, m_firstSelection; uint m_lastPickedPrimitive; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_settings_page.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_settings_page.h index 27cda963e..aa7677b9f 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_settings_page.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_settings_page.h @@ -36,7 +36,7 @@ class WorldEditorSettingsPage : public Core::IOptionsPage { Q_OBJECT public: - WorldEditorSettingsPage(QObject *parent = 0); + explicit WorldEditorSettingsPage(QObject *parent = 0); virtual ~WorldEditorSettingsPage() {} virtual QString id() const; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp index f1b8b17f1..40e69d1f2 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp @@ -63,7 +63,6 @@ WorldEditorWindow::WorldEditorWindow(QWidget *parent) m_ui.graphicsView->setVisibleText(false); m_ui.treePrimitivesView->setModel(m_primitivesModel); - // TODO: ? m_ui.treePrimitivesView->setUndoStack(m_undoStack); m_ui.treePrimitivesView->setZoneBuilder(m_zoneBuilderBase); m_ui.treePrimitivesView->setWorldScene(m_worldEditorScene); @@ -131,7 +130,7 @@ QUndoStack *WorldEditorWindow::undoStack() const void WorldEditorWindow::maybeSave() { - QMessageBox *messageBox = new QMessageBox(tr("SDI"), + QMessageBox *messageBox = new QMessageBox(tr("World Editor"), tr("The data has been modified.\n" "Do you want to save your changes?"), QMessageBox::Warning, @@ -143,7 +142,7 @@ void WorldEditorWindow::maybeSave() messageBox->setButtonText(QMessageBox::Yes, tr("Save")); - messageBox->setButtonText(QMessageBox::No, tr("Don’t Save")); + messageBox->setButtonText(QMessageBox::No, tr("Don't Save")); messageBox->show(); } @@ -175,7 +174,7 @@ void WorldEditorWindow::loadWorldEditFile(const QString &fileName) return; } - m_undoStack->beginMacro(QString("Load %1").arg(fileName)); + m_undoStack->beginMacro(tr("Load %1").arg(fileName)); checkCurrentWorld(); @@ -208,7 +207,6 @@ void WorldEditorWindow::checkCurrentWorld() void WorldEditorWindow::newWorldEditFile() { checkCurrentWorld(); - m_undoStack->push(new CreateWorldCommand("NewWorldEdit", m_primitivesModel)); } @@ -347,7 +345,7 @@ void WorldEditorWindow::hideEvent(QHideEvent *hideEvent) void WorldEditorWindow::createMenus() { - Core::MenuManager *menuManager = Core::ICore::instance()->menuManager(); + //Core::MenuManager *menuManager = Core::ICore::instance()->menuManager(); } void WorldEditorWindow::createToolBars() diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h index d6e3dd593..f289e6c2a 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.h @@ -42,7 +42,7 @@ class WorldEditorWindow: public QMainWindow Q_OBJECT public: - WorldEditorWindow(QWidget *parent = 0); + explicit WorldEditorWindow(QWidget *parent = 0); ~WorldEditorWindow(); QUndoStack *undoStack() const; From 9cea16c0ea809821325b13c5744bdbaa529738da Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Mon, 3 Oct 2011 03:35:05 +0300 Subject: [PATCH 71/89] Changed: #1301 Cleanup code. --HG-- branch : gsoc2011-worldeditorqt --- .../world_editor/world_editor_scene.cpp | 325 +++++++-------- .../plugins/world_editor/world_editor_scene.h | 12 +- .../world_editor/world_editor_scene_item.cpp | 391 ++++-------------- .../world_editor/world_editor_scene_item.h | 80 ++-- 4 files changed, 290 insertions(+), 518 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp index f2103031c..ba67ab9a8 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp @@ -188,7 +188,7 @@ void WorldEditorScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) if (mouseEvent->button() == Qt::LeftButton) { // Create new sub-points - // Call method mousePressEvent for point located under mouse + // Call method mousePressEvent for sub-point located under mouse LandscapeEditor::LandscapeSceneBase::mousePressEvent(mouseEvent); if ((!m_editedSelectedItems && m_selectedPoints.isEmpty()) || @@ -205,7 +205,7 @@ void WorldEditorScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) m_selectedPoints.clear(); // Delete sub-points if it located under mouse - // Call method mousePressEvent for point located under mouse + // Call method mousePressEvent for sub-point located under mouse LandscapeEditor::LandscapeSceneBase::mousePressEvent(mouseEvent); } } @@ -232,119 +232,35 @@ void WorldEditorScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) if (m_mode == WorldEditorScene::SelectMode) m_selectionArea.setTopLeft(mouseEvent->scenePos()); - -// if (m_selectedItems.isEmpty()) -// m_selectionArea.setTopLeft(mouseEvent->scenePos()); } void WorldEditorScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) { if (QApplication::mouseButtons() == Qt::LeftButton) { - QPointF offset(mouseEvent->scenePos() - mouseEvent->lastScenePos()); - m_selectionArea.setBottomRight(mouseEvent->scenePos()); - switch (m_mode) { case WorldEditorScene::SelectMode: break; case WorldEditorScene::MoveMode: - { - if (m_pointsMode) - { - Q_FOREACH(QGraphicsItem *item, m_selectedPoints) - { - item->moveBy(offset.x(), offset.y()); - } - } - else - { - Q_FOREACH(QGraphicsItem *item, m_selectedItems) - { - item->moveBy(offset.x(), offset.y()); - } - } + updateWorldItemsMove(mouseEvent); break; - } case WorldEditorScene::RotateMode: - { - // Caluculate angle between two line - QLineF firstLine(m_pivot, mouseEvent->lastScenePos()); - QLineF secondLine(m_pivot, mouseEvent->scenePos()); - qreal angle = secondLine.angleTo(firstLine); - - m_angle += angle; - - if (m_pointsMode) - { - Q_FOREACH(QGraphicsItem *item, m_selectedPoints) - { - qgraphicsitem_cast(item)->rotateOn(m_pivot, angle); - } - } - else - { - Q_FOREACH(QGraphicsItem *item, m_selectedItems) - { - qgraphicsitem_cast(item)->rotateOn(m_pivot, angle); - } - } + updateWorldItemsRotate(mouseEvent); break; - } case WorldEditorScene::ScaleMode: - { - // Calculate scale factor - if (offset.x() > 0) - offset.setX(1.0 + (offset.x() / 5000)); - else - offset.setX(1.0 / (1.0 + (-offset.x() / 5000))); - - if (offset.y() < 0) - offset.setY(1.0 + (-offset.y() / 5000)); - else - offset.setY(1.0 / (1.0 + (offset.y() / 5000))); - - m_scaleFactor.setX(offset.x() * m_scaleFactor.x()); - m_scaleFactor.setY(offset.y() * m_scaleFactor.y()); - - if (m_pointsMode) - { - Q_FOREACH(QGraphicsItem *item, m_selectedPoints) - { - qgraphicsitem_cast(item)->scaleOn(m_pivot, offset); - } - } - else - { - Q_FOREACH(QGraphicsItem *item, m_selectedItems) - { - qgraphicsitem_cast(item)->scaleOn(m_pivot, offset); - } - } + updateWorldItemsScale(mouseEvent); break; - } case WorldEditorScene::TurnMode: - { - // Caluculate angle between two line - QLineF firstLine(m_pivot, mouseEvent->lastScenePos()); - QLineF secondLine(m_pivot, mouseEvent->scenePos()); - qreal angle = secondLine.angleTo(firstLine); - - m_angle += angle; - - Q_FOREACH(QGraphicsItem *item, m_selectedItems) - { - qgraphicsitem_cast(item)->turnOn(angle); - } - + updateWorldItemsTurn(mouseEvent); break; - } case WorldEditorScene::RadiusMode: + updateWorldItemsRadius(mouseEvent); break; }; - if (m_pointsMode) + if (isEnabledEditPoints()) { if ((editMode() != WorldEditorScene::SelectMode) && (!m_selectedPoints.isEmpty())) m_editedSelectedItems = true; @@ -358,7 +274,7 @@ void WorldEditorScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) else m_editedSelectedItems = false; } - + // Update render update(); } @@ -370,112 +286,63 @@ void WorldEditorScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent) if (mouseEvent->button() == Qt::MidButton) return; - if (m_pointsMode) + if (mouseEvent->button() == Qt::LeftButton) { - if (mouseEvent->button() == Qt::LeftButton) + // Update selection + if ((m_selectionArea.left() != 0) && (m_selectionArea.right() != 0)) { - if ((m_selectionArea.left() != 0) && (m_selectionArea.right() != 0)) - { - QList listItems; + QList listItems; - // Clear selection - updateSelectedPointItems(false); - m_selectedPoints.clear(); + // Clear selection + updateSelectedPointItems(false); + m_selectedPoints.clear(); - if (m_selectionArea.left() < m_selectionArea.right()) - listItems = items(m_selectionArea, Qt::IntersectsItemShape, Qt::AscendingOrder); - else - listItems = items(m_selectionArea, Qt::ContainsItemShape, Qt::AscendingOrder); + // Return list of selected items + if (m_selectionArea.left() < m_selectionArea.right()) + listItems = items(m_selectionArea, Qt::IntersectsItemShape, Qt::AscendingOrder); + else + listItems = items(m_selectionArea, Qt::ContainsItemShape, Qt::AscendingOrder); + if (isEnabledEditPoints()) + { Q_FOREACH(QGraphicsItem *item, listItems) { if (qgraphicsitem_cast(item) == 0) continue; - m_selectedPoints.push_back(item); } updateSelectedPointItems(true); - m_selectionArea = QRectF(); - update(); } else { - if ((!m_editedSelectedItems) && (!m_firstSelection)) - updatePickSelectionPoints(mouseEvent->scenePos()); - else - m_firstSelection = false; - } - } - checkUndo(); - } - else - { - if (mouseEvent->button() != Qt::LeftButton) - return; - - if (m_editedSelectedItems) - { - switch (m_mode) - { - case WorldEditorScene::SelectMode: - break; - - case WorldEditorScene::MoveMode: - { - QPointF offset = mouseEvent->scenePos() - m_firstPick; - m_undoStack->push(new MoveWorldItemsCommand(m_selectedItems, offset, this, m_model)); - break; - } - case WorldEditorScene::RotateMode: - m_undoStack->push(new RotateWorldItemsCommand(m_selectedItems, m_angle, m_pivot, this, m_model)); - break; - case WorldEditorScene::ScaleMode: - m_undoStack->push(new ScaleWorldItemsCommand(m_selectedItems, m_scaleFactor, m_pivot, this, m_model)); - break; - case WorldEditorScene::TurnMode: - m_undoStack->push(new TurnWorldItemsCommand(m_selectedItems, m_angle, this, m_model)); - break; - case WorldEditorScene::RadiusMode: - break; - }; - } - - if ((m_selectionArea.left() != 0) && (m_selectionArea.right() != 0)) - { - QList listItems; - - // Clear selection - updateSelectedWorldItems(false); - m_selectedItems.clear(); - - if (m_selectionArea.left() < m_selectionArea.right()) - listItems = items(m_selectionArea, Qt::IntersectsItemShape, Qt::AscendingOrder); - else - listItems = items(m_selectionArea, Qt::ContainsItemShape, Qt::AscendingOrder); - - Q_FOREACH(QGraphicsItem *item, listItems) - { - if (qgraphicsitem_cast(item) == 0) - continue; - - m_selectedItems.push_back(item); + Q_FOREACH(QGraphicsItem *item, listItems) + { + if (qgraphicsitem_cast(item) == 0) + continue; + m_selectedItems.push_back(item); + } + Q_EMIT updateSelectedItems(m_selectedItems); + updateSelectedWorldItems(true); } - - Q_EMIT updateSelectedItems(m_selectedItems); - - updateSelectedWorldItems(true); m_selectionArea = QRectF(); update(); } else { if ((!m_editedSelectedItems) && (!m_firstSelection)) - updatePickSelection(mouseEvent->scenePos()); + { + if (isEnabledEditPoints()) + updatePickSelectionPoints(mouseEvent->scenePos()); + else + updatePickSelection(mouseEvent->scenePos()); + } else m_firstSelection = false; } - } + if (isEnabledEditPoints()) + checkUndoPointsMode(); + } m_selectionArea = QRectF(); LandscapeEditor::LandscapeSceneBase::mouseReleaseEvent(mouseEvent); } @@ -596,6 +463,32 @@ void WorldEditorScene::updatePickSelectionPoints(const QPointF &point) } void WorldEditorScene::checkUndo() +{ + if (m_editedSelectedItems) + { + switch (m_mode) + { + case WorldEditorScene::SelectMode: + break; + case WorldEditorScene::MoveMode: + m_undoStack->push(new MoveWorldItemsCommand(m_selectedItems, m_offset, this, m_model)); + break; + case WorldEditorScene::RotateMode: + m_undoStack->push(new RotateWorldItemsCommand(m_selectedItems, m_angle, m_pivot, this, m_model)); + break; + case WorldEditorScene::ScaleMode: + m_undoStack->push(new ScaleWorldItemsCommand(m_selectedItems, m_scaleFactor, m_pivot, this, m_model)); + break; + case WorldEditorScene::TurnMode: + m_undoStack->push(new TurnWorldItemsCommand(m_selectedItems, m_angle, this, m_model)); + break; + case WorldEditorScene::RadiusMode: + break; + }; + } +} + +void WorldEditorScene::checkUndoPointsMode() { if (m_pointsMode) { @@ -611,7 +504,6 @@ void WorldEditorScene::checkUndo() worldItem->setShapeChanged(false); } } - if (!items.isEmpty()) { m_undoStack->push(new ShapeWorldItemsCommand(items, polygons, this, m_model)); @@ -620,4 +512,89 @@ void WorldEditorScene::checkUndo() } } +void WorldEditorScene::updateWorldItemsMove(QGraphicsSceneMouseEvent *mouseEvent) +{ + QPointF offset(mouseEvent->scenePos() - mouseEvent->lastScenePos()); + if (m_pointsMode) + Q_FOREACH(QGraphicsItem *item, m_selectedPoints) + { + item->moveBy(offset.x(), offset.y()); + } + else + Q_FOREACH(QGraphicsItem *item, m_selectedItems) + { + item->moveBy(offset.x(), offset.y()); + } +} + +void WorldEditorScene::updateWorldItemsScale(QGraphicsSceneMouseEvent *mouseEvent) +{ + QPointF offset(mouseEvent->scenePos() - mouseEvent->lastScenePos()); + + qreal scaleRatio = 5000; + + // Calculate scale factor + if (offset.x() > 0) + offset.setX(1.0 + (offset.x() / scaleRatio)); + else + offset.setX(1.0 / (1.0 + (-offset.x() / scaleRatio))); + + if (offset.y() < 0) + offset.setY(1.0 - (offset.y() / scaleRatio)); + else + offset.setY(1.0 / (1.0 + (offset.y() / scaleRatio))); + + m_scaleFactor.setX(offset.x() * m_scaleFactor.x()); + m_scaleFactor.setY(offset.y() * m_scaleFactor.y()); + + if (m_pointsMode) + Q_FOREACH(QGraphicsItem *item, m_selectedPoints) + { + qgraphicsitem_cast(item)->scaleOn(m_pivot, offset); + } + else + Q_FOREACH(QGraphicsItem *item, m_selectedItems) + { + qgraphicsitem_cast(item)->scaleOn(m_pivot, offset); + } +} + +void WorldEditorScene::updateWorldItemsRotate(QGraphicsSceneMouseEvent *mouseEvent) +{ + // Caluculate angle between two line + QLineF firstLine(m_pivot, mouseEvent->lastScenePos()); + QLineF secondLine(m_pivot, mouseEvent->scenePos()); + qreal angle = secondLine.angleTo(firstLine); + m_angle += angle; + + if (m_pointsMode) + Q_FOREACH(QGraphicsItem *item, m_selectedPoints) + { + qgraphicsitem_cast(item)->rotateOn(m_pivot, angle); + } + else + Q_FOREACH(QGraphicsItem *item, m_selectedItems) + { + qgraphicsitem_cast(item)->rotateOn(m_pivot, angle); + } +} + +void WorldEditorScene::updateWorldItemsTurn(QGraphicsSceneMouseEvent *mouseEvent) +{ + // Caluculate angle between two line + QLineF firstLine(m_pivot, mouseEvent->lastScenePos()); + QLineF secondLine(m_pivot, mouseEvent->scenePos()); + qreal angle = secondLine.angleTo(firstLine); + m_angle += angle; + + Q_FOREACH(QGraphicsItem *item, m_selectedItems) + { + qgraphicsitem_cast(item)->turnOn(angle); + } +} + +void WorldEditorScene::updateWorldItemsRadius(QGraphicsSceneMouseEvent *mouseEvent) +{ +} + } /* namespace WorldEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h index 833412410..7174c69c8 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.h @@ -105,20 +105,30 @@ private: void updateSelectedWorldItem(QGraphicsItem *item, bool value); void updateSelectedPointItems(bool value); void updateSelectedPointItem(QGraphicsItem *item, bool value); + void updatePickSelection(const QPointF &point); void updatePickSelectionPoints(const QPointF &point); void checkUndo(); + void checkUndoPointsMode(); + + void updateWorldItemsMove(QGraphicsSceneMouseEvent *mouseEvent); + void updateWorldItemsScale(QGraphicsSceneMouseEvent *mouseEvent); + void updateWorldItemsRotate(QGraphicsSceneMouseEvent *mouseEvent); + void updateWorldItemsTurn(QGraphicsSceneMouseEvent *mouseEvent); + void updateWorldItemsRadius(QGraphicsSceneMouseEvent *mouseEvent); QPen m_greenPen, m_purplePen; QBrush m_greenBrush, m_purpleBrush; - QPointF m_firstPick, m_scaleFactor, m_pivot; + QPointF m_firstPick, m_scaleFactor, m_pivot, m_offset; QRectF m_selectionArea; qreal m_firstPickX, m_firstPickY, m_angle; + QList m_selectedItems; QList m_selectedPoints; QList m_polygons; + bool m_editedSelectedItems, m_firstSelection; uint m_lastPickedPrimitive; ModeEdit m_mode; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.cpp index b4d01be65..1375c40ab 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.cpp @@ -180,6 +180,8 @@ void WorldItemPoint::radiusOn(const qreal radius) { if (m_radius == 0) return; + + // TODO: implement } void WorldItemPoint::setColor(const QColor &color) @@ -240,9 +242,6 @@ QRectF WorldItemPoint::boundingRect() const void WorldItemPoint::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *) { - // Here comes the magic: - //painter->setClipRect(option->exposedRect); - painter->setPen(m_pen); // Draw circle @@ -256,90 +255,70 @@ void WorldItemPoint::paint(QPainter *painter, const QStyleOptionGraphicsItem *op painter->drawLines(m_arrow); painter->setPen(Qt::NoPen); -// if (option->state & QStyle::State_Selected) if (isActived()) - { painter->setBrush(m_selectedBrush); - } else - { painter->setBrush(m_brush); - } // Draw point painter->drawRect(m_rect); } -WorldItemPath::WorldItemPath(const QPolygonF &polygon, QGraphicsItem *parent) +BaseWorldItemPolyline::BaseWorldItemPolyline(const QPolygonF &polygon, QGraphicsItem *parent) : AbstractWorldItem(parent), - m_polygon(polygon), + m_polyline(polygon), m_pointEdit(false) { //setFlag(ItemIsSelectable); - - setZValue(WORLD_PATH_LAYER); - - m_pen.setColor(Qt::black); - m_pen.setWidth(3); - m_pen.setJoinStyle(Qt::MiterJoin); - - m_selectedPen.setColor(Qt::white); - m_selectedPen.setWidth(3); - m_selectedPen.setJoinStyle(Qt::MiterJoin); - - QPointF center = m_polygon.boundingRect().center(); - m_polygon.translate(-center); + QPointF center = m_polyline.boundingRect().center(); + m_polyline.translate(-center); setPos(center); } -WorldItemPath::~WorldItemPath() +BaseWorldItemPolyline::~BaseWorldItemPolyline() { } -void WorldItemPath::rotateOn(const QPointF &pivot, const qreal deltaAngle) +void BaseWorldItemPolyline::rotateOn(const QPointF &pivot, const qreal deltaAngle) { prepareGeometryChange(); - QPolygonF rotatedPolygon(m_polygon); + QPolygonF rotatedPolygon(m_polyline); rotatedPolygon.translate(pos() - pivot); QTransform trans; trans = trans.rotate(deltaAngle); - m_polygon = trans.map(rotatedPolygon); + m_polyline = trans.map(rotatedPolygon); - m_polygon.translate(pivot - pos()); + m_polyline.translate(pivot - pos()); } -void WorldItemPath::scaleOn(const QPointF &pivot, const QPointF &factor) +void BaseWorldItemPolyline::scaleOn(const QPointF &pivot, const QPointF &factor) { prepareGeometryChange(); - QPolygonF scaledPolygon(m_polygon); + QPolygonF scaledPolygon(m_polyline); scaledPolygon.translate(pos() - pivot); QTransform trans; trans = trans.scale(factor.x(), factor.y()); - m_polygon = trans.map(scaledPolygon); + m_polyline = trans.map(scaledPolygon); - m_polygon.translate(pivot - pos()); + m_polyline.translate(pivot - pos()); } -void WorldItemPath::setColor(const QColor &color) -{ - m_pen.setColor(color); -} - - -void WorldItemPath::setEnabledSubPoints(bool enabled) +void BaseWorldItemPolyline::setEnabledSubPoints(bool enabled) { m_pointEdit = enabled; if (m_pointEdit) createSubPoints(); else removeSubPoints(); + + setShapeChanged(false); } -void WorldItemPath::moveSubPoint(WorldItemSubPoint *subPoint) +void BaseWorldItemPolyline::moveSubPoint(WorldItemSubPoint *subPoint) { prepareGeometryChange(); @@ -355,12 +334,12 @@ void WorldItemPath::moveSubPoint(WorldItemSubPoint *subPoint) for (int i = 0; i < m_listLines.size(); ++i) m_listLines.at(i).itemPoint->setPos((m_listLines.at(i).lineItem.first->pos() + m_listLines.at(i).lineItem.second->pos()) / 2); - m_polygon = polygon; + m_polyline = polygon; setShapeChanged(true); update(); } -void WorldItemPath::addSubPoint(WorldItemSubPoint *subPoint) +void BaseWorldItemPolyline::addSubPoint(WorldItemSubPoint *subPoint) { prepareGeometryChange(); @@ -402,20 +381,13 @@ void WorldItemPath::addSubPoint(WorldItemSubPoint *subPoint) setShapeChanged(true); } -bool WorldItemPath::removeSubPoint(WorldItemSubPoint *subPoint) +bool BaseWorldItemPolyline::removeSubPoint(WorldItemSubPoint *subPoint) { - int pos = m_listItems.indexOf(subPoint); - - // First and second points can not be removed - if ((pos == 0) || (pos == m_listItems.size() - 1)) - return false; - prepareGeometryChange(); + int pos = m_listItems.indexOf(subPoint); m_listItems.takeAt(pos); - LineStruct newLineItem; - newLineItem.itemPoint = subPoint; // Delete first line @@ -447,66 +419,38 @@ bool WorldItemPath::removeSubPoint(WorldItemSubPoint *subPoint) m_listLines.push_back(newLineItem); subPoint->setFlag(ItemSendsScenePositionChanges, false); setShapeChanged(true); - return true; } -void WorldItemPath::setPolygon(const QPolygonF &polygon) +void BaseWorldItemPolyline::setPolygon(const QPolygonF &polygon) { prepareGeometryChange(); - - m_polygon = polygon; - + m_polyline = polygon; update(); } -QPolygonF WorldItemPath::polygon() const +QPolygonF BaseWorldItemPolyline::polygon() const { - return m_polygon; -} - -QPainterPath WorldItemPath::shape() const -{ - QPainterPath path; - - path.moveTo(m_polygon.first()); - for (int i = 1; i < m_polygon.count(); ++i) - path.lineTo(m_polygon.at(i)); - - return qt_graphicsItem_shapeFromPath(path, m_pen); + return m_polyline; } -QRectF WorldItemPath::boundingRect() const +QRectF BaseWorldItemPolyline::boundingRect() const { - return m_polygon.boundingRect(); + return m_polyline.boundingRect(); } -void WorldItemPath::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *) -{ - // Here comes the magic: - //painter->setClipRect(option->exposedRect); - - //if (option->state & QStyle::State_Selected) - if (isActived()) - painter->setPen(m_selectedPen); - else - painter->setPen(m_pen); - - painter->drawPolyline(m_polygon); -} - -void WorldItemPath::createSubPoints() +void BaseWorldItemPolyline::createSubPoints() { WorldItemSubPoint *firstPoint; firstPoint = new WorldItemSubPoint(WorldItemSubPoint::EdgeType, this); - firstPoint->setPos(m_polygon.front()); + firstPoint->setPos(m_polyline.front()); firstPoint->setFlag(ItemSendsScenePositionChanges); m_listItems.push_back(firstPoint); - for (int i = 1; i < m_polygon.count(); ++i) + for (int i = 1; i < m_polyline.count(); ++i) { WorldItemSubPoint *secondPoint = new WorldItemSubPoint(WorldItemSubPoint::EdgeType, this); - secondPoint->setPos(m_polygon.at(i)); + secondPoint->setPos(m_polyline.at(i)); secondPoint->setFlag(ItemSendsScenePositionChanges); WorldItemSubPoint *middlePoint = new WorldItemSubPoint(WorldItemSubPoint::MiddleType, this); @@ -522,7 +466,7 @@ void WorldItemPath::createSubPoints() } } -void WorldItemPath::removeSubPoints() +void BaseWorldItemPolyline::removeSubPoints() { for (int i = 0; i < m_listLines.count(); ++i) delete m_listLines.at(i).itemPoint; @@ -534,226 +478,106 @@ void WorldItemPath::removeSubPoints() m_listLines.clear(); } -WorldItemZone::WorldItemZone(const QPolygonF &polygon, QGraphicsItem *parent) - : AbstractWorldItem(parent), - m_polygon(polygon), - m_pointEdit(false) +WorldItemPath::WorldItemPath(const QPolygonF &polygon, QGraphicsItem *parent) + : BaseWorldItemPolyline(polygon, parent) { - //setFlag(ItemIsSelectable); - - setZValue(WORLD_ZONE_LAYER); + setZValue(WORLD_PATH_LAYER); - m_pen.setColor(QColor(20, 100, 255)); - m_pen.setWidth(0); + m_pen.setColor(Qt::black); + m_pen.setWidth(3); + m_pen.setJoinStyle(Qt::MiterJoin); m_selectedPen.setColor(Qt::white); - m_selectedPen.setWidth(0); - - m_brush.setColor(QColor(20, 100, 255, TRANSPARENCY)); - m_brush.setStyle(Qt::SolidPattern); - - m_selectedBrush.setColor(QColor(255, 255, 255, 100)); - m_selectedBrush.setStyle(Qt::SolidPattern); - - QPointF center = m_polygon.boundingRect().center(); - m_polygon.translate(-center); - setPos(center); + m_selectedPen.setWidth(3); + m_selectedPen.setJoinStyle(Qt::MiterJoin); } -WorldItemZone::~WorldItemZone() +WorldItemPath::~WorldItemPath() { } -void WorldItemZone::rotateOn(const QPointF &pivot, const qreal deltaAngle) +void WorldItemPath::setColor(const QColor &color) { - prepareGeometryChange(); - - QPolygonF rotatedPolygon(m_polygon); - rotatedPolygon.translate(pos() - pivot); - - QTransform trans; - trans = trans.rotate(deltaAngle); - m_polygon = trans.map(rotatedPolygon); - - m_polygon.translate(pivot - pos()); + m_pen.setColor(color); } -void WorldItemZone::scaleOn(const QPointF &pivot, const QPointF &factor) +bool WorldItemPath::removeSubPoint(WorldItemSubPoint *subPoint) { - prepareGeometryChange(); - - QPolygonF scaledPolygon(m_polygon); - scaledPolygon.translate(pos() - pivot); + int pos = m_listItems.indexOf(subPoint); - QTransform trans; - trans = trans.scale(factor.x(), factor.y()); - m_polygon = trans.map(scaledPolygon); + // First and second points can not be removed + if ((pos == 0) || (pos == m_listItems.size() - 1)) + return false; - m_polygon.translate(pivot - pos()); + return BaseWorldItemPolyline::removeSubPoint(subPoint); } -void WorldItemZone::setColor(const QColor &color) +QPainterPath WorldItemPath::shape() const { - m_pen.setColor(color); + QPainterPath path; - QColor brushColor(color); - brushColor.setAlpha(TRANSPARENCY); + path.moveTo(m_polyline.first()); + for (int i = 1; i < m_polyline.count(); ++i) + path.lineTo(m_polyline.at(i)); - m_brush.setColor(brushColor); + return qt_graphicsItem_shapeFromPath(path, m_pen); } -void WorldItemZone::setEnabledSubPoints(bool enabled) +void WorldItemPath::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *) { - m_pointEdit = enabled; - if (m_pointEdit) - createSubPoints(); + if (isActived()) + painter->setPen(m_selectedPen); else - removeSubPoints(); + painter->setPen(m_pen); - setShapeChanged(false); + painter->drawPolyline(m_polyline); } -void WorldItemZone::moveSubPoint(WorldItemSubPoint *subPoint) -{ - prepareGeometryChange(); - - QPolygonF polygon; - // Update polygon - Q_FOREACH(WorldItemSubPoint *node, m_listItems) - { - polygon << node->pos(); - } - - // Update middle points - for (int i = 0; i < m_listLines.size(); ++i) - m_listLines.at(i).itemPoint->setPos((m_listLines.at(i).lineItem.first->pos() + m_listLines.at(i).lineItem.second->pos()) / 2); - - m_polygon = polygon; - update(); - - setShapeChanged(true); -} - -void WorldItemZone::addSubPoint(WorldItemSubPoint *subPoint) +WorldItemZone::WorldItemZone(const QPolygonF &polygon, QGraphicsItem *parent) + : BaseWorldItemPolyline(polygon, parent) { - prepareGeometryChange(); - - for (int i = 0; i < m_listLines.size(); ++i) - { - if (subPoint == m_listLines.at(i).itemPoint) - { - LineStruct oldLineItem = m_listLines[i]; - - // Create the first middle sub-point - WorldItemSubPoint *firstItem = new WorldItemSubPoint(WorldItemSubPoint::MiddleType, this); - firstItem->setPos((oldLineItem.lineItem.first->pos() + subPoint->pos()) / 2); - - // Create the second middle sub-point - WorldItemSubPoint *secondItem = new WorldItemSubPoint(WorldItemSubPoint::MiddleType, this); - secondItem->setPos((oldLineItem.lineItem.second->pos() + subPoint->pos()) / 2); - - // Add first line in the list - LineStruct firstNewLineItem; - firstNewLineItem.itemPoint = firstItem; - firstNewLineItem.lineItem = LineItem(oldLineItem.lineItem.first, subPoint); - m_listLines.push_back(firstNewLineItem); - - // Add second line in the list - LineStruct secondNewLineItem; - secondNewLineItem.itemPoint = secondItem; - secondNewLineItem.lineItem = LineItem(subPoint, oldLineItem.lineItem.second); - m_listLines.push_back(secondNewLineItem); - - m_listLines.removeAt(i); - - int pos = m_listItems.indexOf(oldLineItem.lineItem.second); - m_listItems.insert(pos, subPoint); - subPoint->setFlag(ItemSendsScenePositionChanges); + setZValue(WORLD_ZONE_LAYER); - break; - } - } - setShapeChanged(true); + m_pen.setColor(QColor(20, 100, 255)); + m_pen.setWidth(0); + m_selectedPen.setColor(Qt::white); + m_selectedPen.setWidth(0); + m_brush.setColor(QColor(20, 100, 255, TRANSPARENCY)); + m_brush.setStyle(Qt::SolidPattern); + m_selectedBrush.setColor(QColor(255, 255, 255, 100)); + m_selectedBrush.setStyle(Qt::SolidPattern); } -bool WorldItemZone::removeSubPoint(WorldItemSubPoint *subPoint) +WorldItemZone::~WorldItemZone() { - prepareGeometryChange(); - - if (m_listItems.size() < 4) - return false; - - int pos = m_listItems.indexOf(subPoint); - m_listItems.takeAt(pos); - - LineStruct newLineItem; - - newLineItem.itemPoint = subPoint; - - // Delete first line - for (int i = 0; i < m_listLines.size(); ++i) - { - if (subPoint == m_listLines.at(i).lineItem.first) - { - // Saving second point for new line - newLineItem.lineItem.second = m_listLines.at(i).lineItem.second; - delete m_listLines.at(i).itemPoint; - m_listLines.removeAt(i); - break; - } - } - - // Delete second line - for (int i = 0; i < m_listLines.size(); ++i) - { - if (subPoint == m_listLines.at(i).lineItem.second) - { - // Saving first point for new line - newLineItem.lineItem.first = m_listLines.at(i).lineItem.first; - delete m_listLines.at(i).itemPoint; - m_listLines.removeAt(i); - break; - } - } - m_listLines.push_back(newLineItem); - subPoint->setPos((newLineItem.lineItem.first->pos() + newLineItem.lineItem.second->pos()) / 2); - subPoint->setFlag(ItemSendsScenePositionChanges, false); - - setShapeChanged(true); - - return true; } -void WorldItemZone::setPolygon(const QPolygonF &polygon) +void WorldItemZone::setColor(const QColor &color) { - prepareGeometryChange(); - - m_polygon = polygon; - - update(); + m_pen.setColor(color); + QColor brushColor(color); + brushColor.setAlpha(TRANSPARENCY); + m_brush.setColor(brushColor); } -QPolygonF WorldItemZone::polygon() const +bool WorldItemZone::removeSubPoint(WorldItemSubPoint *subPoint) { - return m_polygon; -} + if (m_listItems.size() < 4) + return false; -QRectF WorldItemZone::boundingRect() const -{ - return m_polygon.boundingRect(); + return BaseWorldItemPolyline::removeSubPoint(subPoint); } QPainterPath WorldItemZone::shape() const { QPainterPath path; - path.addPolygon(m_polygon); + path.addPolygon(m_polyline); return qt_graphicsItem_shapeFromPath(path, m_pen); } void WorldItemZone::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *) { -// if (option->state & QStyle::State_Selected) if (isActived()) { painter->setPen(m_selectedPen); @@ -765,34 +589,12 @@ void WorldItemZone::paint(QPainter *painter, const QStyleOptionGraphicsItem *opt painter->setBrush(m_brush); } - painter->drawPolygon(m_polygon); + painter->drawPolygon(m_polyline); } void WorldItemZone::createSubPoints() { - WorldItemSubPoint *firstPoint; - firstPoint = new WorldItemSubPoint(WorldItemSubPoint::EdgeType, this); - firstPoint->setPos(m_polygon.front()); - firstPoint->setFlag(ItemSendsScenePositionChanges); - m_listItems.push_back(firstPoint); - - for (int i = 1; i < m_polygon.count(); ++i) - { - WorldItemSubPoint *secondPoint = new WorldItemSubPoint(WorldItemSubPoint::EdgeType, this); - secondPoint->setPos(m_polygon.at(i)); - secondPoint->setFlag(ItemSendsScenePositionChanges); - - WorldItemSubPoint *middlePoint = new WorldItemSubPoint(WorldItemSubPoint::MiddleType, this); - middlePoint->setPos((firstPoint->pos() + secondPoint->pos()) / 2); - - LineStruct newLineItem; - newLineItem.itemPoint = middlePoint; - newLineItem.lineItem = LineItem(firstPoint, secondPoint); - m_listLines.push_back(newLineItem); - - firstPoint = secondPoint; - m_listItems.push_back(firstPoint); - } + BaseWorldItemPolyline::createSubPoints(); LineStruct endLineItem; endLineItem.itemPoint = new WorldItemSubPoint(WorldItemSubPoint::MiddleType, this); @@ -801,18 +603,6 @@ void WorldItemZone::createSubPoints() m_listLines.push_back(endLineItem); } -void WorldItemZone::removeSubPoints() -{ - for (int i = 0; i < m_listLines.count(); ++i) - delete m_listLines.at(i).itemPoint; - - for (int i = 0; i < m_listItems.count(); ++i) - delete m_listItems.at(i); - - m_listItems.clear(); - m_listLines.clear(); -} - //******************************************* WorldItemSubPoint::WorldItemSubPoint(SubPointType pointType, AbstractWorldItem *parent) @@ -859,8 +649,6 @@ void WorldItemSubPoint::rotateOn(const QPointF &pivot, const qreal deltaAngle) prepareGeometryChange(); QPolygonF rotatedPolygon(m_rect); - - // TODO rotatedPolygon.translate(scenePos() - pivot); QTransform trans; @@ -876,8 +664,6 @@ void WorldItemSubPoint::scaleOn(const QPointF &pivot, const QPointF &factor) prepareGeometryChange(); QPolygonF scaledPolygon(m_rect); - - // TODO scaledPolygon.translate(scenePos() - pivot); QTransform trans; @@ -896,7 +682,6 @@ QRectF WorldItemSubPoint::boundingRect() const void WorldItemSubPoint::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { painter->setPen(Qt::NoPen); - if (m_type == WorldItemSubPoint::EdgeType) { if (isActived()) @@ -905,9 +690,7 @@ void WorldItemSubPoint::paint(QPainter *painter, const QStyleOptionGraphicsItem painter->setBrush(m_brush); } else - { painter->setBrush(m_brushMiddle); - } // Draw point painter->drawRect(m_rect); @@ -955,4 +738,4 @@ void WorldItemSubPoint::updateBoundingRect() m_boundingRect.setCoords(-SIZE_POINT, -SIZE_POINT, SIZE_POINT, SIZE_POINT); } -} /* namespace WorldEditor */ +} /* namespace WorldEditor */ \ No newline at end of file diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h index 9136712c5..b5584c427 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h @@ -66,21 +66,21 @@ public: enum { Type = QGraphicsItem::UserType + 1 }; /// Rotate item around @pivot point on &deltaAngle (deg). - virtual void rotateOn(const QPointF &pivot, const qreal deltaAngle) {}; + virtual void rotateOn(const QPointF &pivot, const qreal deltaAngle) {} /// Scales item relatively @pivot point // TODO: add modes: IgnoreAspectRatio, KeepAspectRatio - virtual void scaleOn(const QPointF &pivot, const QPointF &factor) {}; + virtual void scaleOn(const QPointF &pivot, const QPointF &factor) {} /// Rotate arrow on angle (deg). (only for WorldItemPoint) - virtual void turnOn(const qreal angle) {}; - virtual void radiusOn(const qreal radius) {}; + virtual void turnOn(const qreal angle) {} + virtual void radiusOn(const qreal radius) {} /// Change color - virtual void setColor(const QColor &color) = 0; + virtual void setColor(const QColor &color) {} /// Enable/disable the mode edit shape (only for WorldItemPath and WorldItemPath) - virtual void setEnabledSubPoints(bool enabled) = 0; + virtual void setEnabledSubPoints(bool enabled) {} virtual void moveSubPoint(WorldItemSubPoint *subPoint) {} virtual void addSubPoint(WorldItemSubPoint *subPoint) {} @@ -156,22 +156,20 @@ private: }; /* -@class WorldItemPath -@brief WorldItemPath class provides a polyline item that you can add to a WorldEditorScene. +@class BaseWorldItemPolyline +@brief @details */ -class WorldItemPath: public AbstractWorldItem +class BaseWorldItemPolyline: public AbstractWorldItem { public: - WorldItemPath(const QPolygonF &polygon, QGraphicsItem *parent = 0); - virtual ~WorldItemPath(); + BaseWorldItemPolyline(const QPolygonF &polygon, QGraphicsItem *parent = 0); + virtual ~BaseWorldItemPolyline(); virtual void rotateOn(const QPointF &pivot, const qreal deltaAngle); virtual void scaleOn(const QPointF &pivot, const QPointF &factor); - virtual void setColor(const QColor &color); virtual void setEnabledSubPoints(bool enabled); - virtual void moveSubPoint(WorldItemSubPoint *subPoint); virtual void addSubPoint(WorldItemSubPoint *subPoint); virtual bool removeSubPoint(WorldItemSubPoint *subPoint); @@ -180,62 +178,66 @@ public: virtual QPolygonF polygon() const; virtual QRectF boundingRect() const; - virtual QPainterPath shape() const; - virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); -private: - void createSubPoints(); - void removeSubPoints(); +protected: + virtual void createSubPoints(); + virtual void removeSubPoints(); - QPen m_pen, m_selectedPen; - QPolygonF m_polygon; bool m_pointEdit; + QPolygonF m_polyline; + QPen m_pen, m_selectedPen; QList m_listItems; QList m_listLines; }; +/* +@class WorldItemPath +@brief WorldItemPath class provides a polyline item that you can add to a WorldEditorScene. +@details +*/ +class WorldItemPath: public BaseWorldItemPolyline +{ +public: + WorldItemPath(const QPolygonF &polygon, QGraphicsItem *parent = 0); + virtual ~WorldItemPath(); + + virtual void setColor(const QColor &color); + virtual bool removeSubPoint(WorldItemSubPoint *subPoint); + virtual QPainterPath shape() const; + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + +private: + + QPen m_pen, m_selectedPen; +}; + /* @class WorldItemZone @brief The WorldItemZone class provides a polygon item that you can add to a WorldEditorScene. @details */ -class WorldItemZone: public AbstractWorldItem +class WorldItemZone: public BaseWorldItemPolyline { public: WorldItemZone(const QPolygonF &polygon, QGraphicsItem *parent = 0); virtual ~WorldItemZone(); - virtual void rotateOn(const QPointF &pivot, const qreal deltaAngle); - virtual void scaleOn(const QPointF &pivot, const QPointF &factor); virtual void setColor(const QColor &color); - virtual void setEnabledSubPoints(bool enabled); - - virtual void moveSubPoint(WorldItemSubPoint *subPoint); - virtual void addSubPoint(WorldItemSubPoint *subPoint); virtual bool removeSubPoint(WorldItemSubPoint *subPoint); - virtual void setPolygon(const QPolygonF &polygon); - virtual QPolygonF polygon() const; - - virtual QRectF boundingRect() const; virtual QPainterPath shape() const; virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); -private: - void createSubPoints(); - void removeSubPoints(); +protected: + virtual void createSubPoints(); +private: static const int TRANSPARENCY = 38; QPen m_pen, m_selectedPen; QBrush m_brush, m_selectedBrush; - QPolygonF m_polygon; - bool m_pointEdit; - - QList m_listItems; - QList m_listLines; }; /* From c4257403618442a037e99ba4e9f67e91b84e837b Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Tue, 11 Oct 2011 13:44:53 +0300 Subject: [PATCH 72/89] Changed: #1302 Fixed undo/redo in world editor qt. --HG-- branch : gsoc2011-worldeditorqt --- .../src/plugins/world_editor/world_editor_constants.h | 4 ++++ .../src/plugins/world_editor/world_editor_misc.cpp | 2 +- .../src/plugins/world_editor/world_editor_scene.cpp | 4 +++- .../src/plugins/world_editor/world_editor_scene_item.h | 2 -- .../src/plugins/world_editor/world_editor_window.cpp | 4 ++-- .../src/plugins/world_editor/world_editor_window.ui | 2 +- 6 files changed, 11 insertions(+), 7 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_constants.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_constants.h index a75e2148b..d0617373e 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_constants.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_constants.h @@ -32,6 +32,10 @@ const int PRIMITIVE_IS_MODIFIED = USER_TYPE + 5; const int PRIMITIVE_FILE_IS_CREATED = USER_TYPE + 6; const int PRIMITIVE_IS_VISIBLE = USER_TYPE + 7; +//properties editor +const char *const DIFFERENT_VALUE_STRING = ""; +const char *const DIFFERENT_VALUE_MULTI_STRING = ""; + //settings const char *const WORLD_EDITOR_SECTION = "WorldEditor"; const char *const WORLD_WINDOW_STATE = "WorldWindowState"; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_misc.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_misc.cpp index 6db59f9e5..dc1ae435f 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_misc.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_misc.cpp @@ -171,7 +171,7 @@ bool loadWorldEditFile(const std::string &fileName, WorldEditList &worldEditList NLLIGO::CPrimitives ligoPrimitives; // Read it - ligoPrimitives.read(primitives, fileName.c_str(), *NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig); + ligoPrimitives.read(primitives, fileName.c_str(), *ligoConfig()); //_DataHierarchy.back ().Primitives.read (primitives, filename, theApp.Config); // Set the filename diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp index ba67ab9a8..9922daaf7 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp @@ -181,7 +181,7 @@ void WorldEditorScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) { m_firstPick = mouseEvent->scenePos(); - if (m_pointsMode) + if (isEnabledEditPoints()) { m_polygons = polygonsFromItems(m_selectedItems); @@ -288,6 +288,8 @@ void WorldEditorScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent) if (mouseEvent->button() == Qt::LeftButton) { + checkUndo(); + // Update selection if ((m_selectionArea.left() != 0) && (m_selectionArea.right() != 0)) { diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h index b5584c427..9752d783d 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene_item.h @@ -223,10 +223,8 @@ public: WorldItemZone(const QPolygonF &polygon, QGraphicsItem *parent = 0); virtual ~WorldItemZone(); - virtual void setColor(const QColor &color); virtual bool removeSubPoint(WorldItemSubPoint *subPoint); - virtual QPainterPath shape() const; virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp index 40e69d1f2..1e6d44ff6 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp @@ -384,8 +384,8 @@ void WorldEditorWindow::readSettings() // Use OpenGL graphics system instead raster graphics system if (settings->value(Constants::WORLD_EDITOR_USE_OPENGL, true).toBool()) { - //m_oglWidget = new QGLWidget(QGLFormat(QGL::DoubleBuffer)); - m_oglWidget = new QGLWidget(QGLFormat(QGL::DoubleBuffer | QGL::SampleBuffers)); + m_oglWidget = new QGLWidget(QGLFormat(QGL::DoubleBuffer)); + //m_oglWidget = new QGLWidget(QGLFormat(QGL::DoubleBuffer | QGL::SampleBuffers)); m_ui.graphicsView->setViewport(m_oglWidget); } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui index d6d4edb28..d9b6f8ac3 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.ui @@ -28,7 +28,7 @@ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - QPainter::Antialiasing|QPainter::SmoothPixmapTransform|QPainter::TextAntialiasing + QPainter::SmoothPixmapTransform QGraphicsView::NoDrag From 8a7b7ecd0b70bc83e6bdef55c79870a86ed64695 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Wed, 21 Dec 2011 00:45:00 +0300 Subject: [PATCH 73/89] Changed: #1302 Added some stuff for weqt property editor. --HG-- branch : gsoc2011-worldeditorqt --- .../src/plugins/core/CMakeLists.txt | 1 - .../landscape_editor/list_zones_model.cpp | 4 +- .../world_editor/property_editor_widget.cpp | 111 +++++++++++++++++- .../world_editor/property_editor_widget.h | 7 +- .../world_editor/world_editor_window.cpp | 2 +- 5 files changed, 117 insertions(+), 8 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/CMakeLists.txt index 3140f02fb..927e35eaa 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/core/CMakeLists.txt +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/core/CMakeLists.txt @@ -11,7 +11,6 @@ SET(OVQT_EXT_SYS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/../../extension_system/iplugin. SET(OVQT_CORE_PLUGIN_HDR icore.h icontext.h - imenu_manager.h icore_listener.h ioptions_page.h core_plugin.h diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_model.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_model.cpp index 57e8683c0..103a43052 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_model.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/list_zones_model.cpp @@ -75,9 +75,7 @@ QVariant ListZonesModel::data(const QModelIndex &index, int role) const } } -QVariant ListZonesModel::headerData(int section, - Qt::Orientation /* orientation */, - int role) const +QVariant ListZonesModel::headerData(int section, Qt::Orientation, int role) const { return QVariant(); } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.cpp index 7df0b6d1d..7b4224e04 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.cpp @@ -37,12 +37,16 @@ PropertyEditorWidget::PropertyEditorWidget(QWidget *parent) m_ui.setupUi(this); m_variantManager = new QtVariantPropertyManager(this); - + m_enumManager = new QtEnumPropertyManager(this); connect(m_variantManager, SIGNAL(valueChanged(QtProperty *, const QVariant &)), this, SLOT(valueChanged(QtProperty *, const QVariant &))); QtVariantEditorFactory *variantFactory = new QtVariantEditorFactory(this); + QtEnumEditorFactory *enumFactory = new QtEnumEditorFactory(this); m_ui.treePropertyBrowser->setFactoryForManager(m_variantManager, variantFactory); + m_ui.treePropertyBrowser->setFactoryForManager(m_enumManager, enumFactory); + + m_groupManager = new QtGroupPropertyManager(this); } PropertyEditorWidget::~PropertyEditorWidget() @@ -51,10 +55,113 @@ PropertyEditorWidget::~PropertyEditorWidget() void PropertyEditorWidget::clearProperties() { + m_ui.treePropertyBrowser->clear(); } -void PropertyEditorWidget::setCurrentPrimitive(PrimitiveNode *node) +void PropertyEditorWidget::updateSelection(const NodeList &selected, const NodeList &deselected) { + clearProperties(); + + // The parameter list + std::set parameterList; + + for (int i = 0; i < selected.size(); ++i) + { + if (selected.at(i)->type() == Node::RootPrimitiveNodeType) + { + /* + const_cast(_PropDlgLocators[i].Primitive)->removePropertyByName("name"); + const_cast(_PropDlgLocators[i].Primitive)->removePropertyByName("path"); + //TODO faire une fonction dans CWorldDoc pour recup m_strPathName + string name; + getDocument()->getPrimitiveDisplayName(name,_PropDlgLocators[i].getDatabaseIndex()); + string path; + getDocument()->getFilePath(_PropDlgLocators[i].getDatabaseIndex(),path); + + const_cast(_PropDlgLocators[i].Primitive)->addPropertyByName("name",new CPropertyString (name)); + const_cast(_PropDlgLocators[i].Primitive)->addPropertyByName("path",new CPropertyString (path)); + */ + } + + if (selected.at(i)->type() == Node::PrimitiveNodeType) + { + PrimitiveNode *node = static_cast(selected.at(i)); + const NLLIGO::IPrimitive *primitive = node->primitive(); + const NLLIGO::CPrimitiveClass *primClass = node->primitiveClass(); + + // Use the class or not ? + if (primClass) + { + QtProperty *groupNode; + groupNode = m_groupManager->addProperty(node->data(Qt::DisplayRole).toString()); + m_ui.treePropertyBrowser->addProperty(groupNode); + + // For each properties of the class + for (uint p = 0; p < primClass->Parameters.size(); p++) + { + // Is the parameter visible ? + if (primClass->Parameters[p].Visible) + { + QtProperty *param; + + if (primClass->Parameters[p].Type == NLLIGO::CPrimitiveClass::CParameter::Boolean) + param = m_variantManager->addProperty(QVariant::Bool, primClass->Parameters[p].Name.c_str()); + else if (primClass->Parameters[p].Type == NLLIGO::CPrimitiveClass::CParameter::ConstString) + { + param = m_enumManager->addProperty(primClass->Parameters[p].Name.c_str()); + } + else if (primClass->Parameters[p].Type == NLLIGO::CPrimitiveClass::CParameter::String) + param = m_variantManager->addProperty(QVariant::String, primClass->Parameters[p].Name.c_str()); + else + param = m_variantManager->addProperty(QVariant::String, primClass->Parameters[p].Name.c_str()); + + groupNode->addSubProperty(param); + + parameterList.insert(primClass->Parameters[p]); + } + } + } + else + { + // For each primitive property + uint numProp = primitive->getNumProperty(); + for (uint p = 0; p < numProp; p++) + { + // Get the property + std::string propertyName; + const NLLIGO::IProperty *prop; + nlverify(primitive->getProperty (p, propertyName, prop)); + + // Add a default property + NLLIGO::CPrimitiveClass::CParameter defProp(*prop, propertyName.c_str()); + parameterList.insert(defProp); + } + } + } + } + + // Remove property class + std::set::iterator ite = parameterList.begin (); + while (ite != parameterList.end ()) + { + // Next iterator + std::set::iterator next = ite; + next++; + + // Property name ? + if (ite->Name == "class") + { + // Remove it + parameterList.erase (ite); + } + + ite = next; + } + + // Add the default parameter + NLLIGO::CPrimitiveClass::CParameter defaultParameter; + defaultParameter.Visible = true; + defaultParameter.Filename = false; } } /* namespace WorldEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.h index 3ee73a293..3a2506def 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.h @@ -50,11 +50,16 @@ public: public Q_SLOTS: void clearProperties(); - void setCurrentPrimitive(PrimitiveNode *node); + + /// Update of selections + void updateSelection(const NodeList &selected, const NodeList &deselected); private: QtVariantPropertyManager *m_variantManager; + QtEnumPropertyManager *m_enumManager; + QtGroupPropertyManager *m_groupManager; + Ui::PropertyEditorWidget m_ui; }; /* PropertyEditorWidget */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp index 1e6d44ff6..30173b9d9 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp @@ -276,7 +276,7 @@ void WorldEditorWindow::updateSelection(const QItemSelection &selected, const QI } // TODO: update property editor - // ... + m_ui.propertyEditWidget->updateSelection(nodesSelected, nodesDeselected); QList itemSelected; Q_FOREACH(Node *node, nodesSelected) From 6f3e096a3eae701b6f686954e15f2a4ca9ca4e2f Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Mon, 16 Jan 2012 01:18:27 +0300 Subject: [PATCH 74/89] Fixed: #1301 Fixed crash program --HG-- branch : gsoc2011-worldeditorqt --- .../src/plugins/landscape_editor/builder_zone_region.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.cpp index e84a81f57..33b48e04e 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.cpp @@ -858,7 +858,7 @@ void BuilderZoneRegion::putTransitions (sint32 inX, sint32 inY, const NLLIGO::SP if ( (corner < 4) && (m != 0) ) { // The material can't be paused - for (int t = 0; i < 4; ++t) + for (int t = 0; t < 4; ++t) dataZoneTemp.sharingMatNames[t] = STRING_UNUSED; // Don't propagate any more From 59eac847978a62bd466e0a73e3934b06e838fe41 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Sat, 4 Feb 2012 20:58:21 +0300 Subject: [PATCH 75/89] Changed: #1302 Added text edit property in qt property browser for NLLIGO::CPropertyStringArray. --HG-- branch : gsoc2011-worldeditorqt --- .../qtpropertybrowser/qteditorfactory.cpp | 232 ++++++++++++++++++ .../qtpropertybrowser/qteditorfactory.h | 22 ++ .../qtpropertybrowserutils.cpp | 4 + .../qtpropertybrowserutils_p.h | 2 + .../qtpropertybrowser/qtpropertymanager.cpp | 15 ++ .../qtpropertybrowser/qtpropertymanager.h | 10 + 6 files changed, 285 insertions(+) diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qteditorfactory.cpp b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qteditorfactory.cpp index e619cf8cb..3a1e874eb 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qteditorfactory.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qteditorfactory.cpp @@ -101,6 +101,13 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#include #include #include @@ -2601,6 +2608,231 @@ void QtFontEditorFactory::disconnectPropertyManager(QtFontPropertyManager *manag disconnect(manager, SIGNAL(valueChanged(QtProperty*,QFont)), this, SLOT(slotPropertyChanged(QtProperty*,QFont))); } +class QtTextEditWidget : public QWidget { + Q_OBJECT + +public: + QtTextEditWidget(QWidget *parent); + + bool eventFilter(QObject *obj, QEvent *ev); + +public Q_SLOTS: + void setValue(const QString &value); + +private Q_SLOTS: + void buttonClicked(); + +Q_SIGNALS: + void valueChanged(const QString &value); + +private: + QLineEdit *m_lineEdit; + QToolButton *m_defaultButton; + QToolButton *m_button; +}; + +QtTextEditWidget::QtTextEditWidget(QWidget *parent) : + QWidget(parent), + m_lineEdit(new QLineEdit), + m_defaultButton(new QToolButton), + m_button(new QToolButton) +{ + QHBoxLayout *lt = new QHBoxLayout(this); + lt->setContentsMargins(0, 0, 0, 0); + lt->setSpacing(0); + lt->addWidget(m_lineEdit); + m_lineEdit->setReadOnly(true); + + m_button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Ignored); + m_button->setFixedWidth(20); + setFocusProxy(m_button); + setFocusPolicy(m_button->focusPolicy()); + m_button->setText(tr("...")); + m_button->installEventFilter(this); + connect(m_button, SIGNAL(clicked()), this, SLOT(buttonClicked())); + lt->addWidget(m_button); + lt->addWidget(m_defaultButton); + m_defaultButton->setEnabled(false); +} + +void QtTextEditWidget::setValue(const QString &value) +{ + if (m_lineEdit->text() != value) + m_lineEdit->setText(value); +} + +void QtTextEditWidget::buttonClicked() +{ + QGridLayout *gridLayout; + QPlainTextEdit *plainTextEdit; + QDialogButtonBox *buttonBox; + QDialog *dialog; + + dialog = new QDialog(this); + dialog->resize(400, 300); + gridLayout = new QGridLayout(dialog); + plainTextEdit = new QPlainTextEdit(dialog); + + gridLayout->addWidget(plainTextEdit, 0, 0, 1, 1); + + buttonBox = new QDialogButtonBox(dialog); + buttonBox->setOrientation(Qt::Horizontal); + buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok); + + gridLayout->addWidget(buttonBox, 1, 0, 1, 1); + + QObject::connect(buttonBox, SIGNAL(accepted()), dialog, SLOT(accept())); + QObject::connect(buttonBox, SIGNAL(rejected()), dialog, SLOT(reject())); + + plainTextEdit->textCursor().insertText(m_lineEdit->text()); + + dialog->setModal(true); + dialog->show(); + int result = dialog->exec(); + + if (result == QDialog::Accepted) + { + QString newText = plainTextEdit->document()->toPlainText(); + + setValue(newText); + if (plainTextEdit->document()->isModified()) + Q_EMIT valueChanged(newText); + } + + delete dialog; +} + +bool QtTextEditWidget::eventFilter(QObject *obj, QEvent *ev) +{ + if (obj == m_button) { + switch (ev->type()) { + case QEvent::KeyPress: + case QEvent::KeyRelease: { // Prevent the QToolButton from handling Enter/Escape meant control the delegate + switch (static_cast(ev)->key()) { + case Qt::Key_Escape: + case Qt::Key_Enter: + case Qt::Key_Return: + ev->ignore(); + return true; + default: + break; + } + } + break; + default: + break; + } + } + return QWidget::eventFilter(obj, ev); +} + +// QtLineEditFactory + +class QtTextEditorFactoryPrivate : public EditorFactoryPrivate +{ + QtTextEditorFactory *q_ptr; + Q_DECLARE_PUBLIC(QtTextEditorFactory) +public: + + void slotPropertyChanged(QtProperty *property, const QString &value); + void slotSetValue(const QString &value); +}; + +void QtTextEditorFactoryPrivate::slotPropertyChanged(QtProperty *property, + const QString &value) +{ + const PropertyToEditorListMap::iterator it = m_createdEditors.find(property); + if (it == m_createdEditors.end()) + return; + QListIterator itEditor(it.value()); + + while (itEditor.hasNext()) + itEditor.next()->setValue(value); +} + +void QtTextEditorFactoryPrivate::slotSetValue(const QString &value) +{ + QObject *object = q_ptr->sender(); + const EditorToPropertyMap::ConstIterator ecend = m_editorToProperty.constEnd(); + for (EditorToPropertyMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor) + if (itEditor.key() == object) { + QtProperty *property = itEditor.value(); + QtTextPropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + manager->setValue(property, value); + return; + } +} +/*! + \class QtTextEditFactory + + \brief The QtTextEditFactory class provides QTextEdit widgets for + properties created by QtStringPropertyManager objects. + + \sa QtAbstractEditorFactory, QtStringPropertyManager +*/ + +/*! + Creates a factory with the given \a parent. +*/ +QtTextEditorFactory::QtTextEditorFactory(QObject *parent) + : QtAbstractEditorFactory(parent) +{ + d_ptr = new QtTextEditorFactoryPrivate(); + d_ptr->q_ptr = this; + +} + +/*! + Destroys this factory, and all the widgets it has created. +*/ +QtTextEditorFactory::~QtTextEditorFactory() +{ + qDeleteAll(d_ptr->m_editorToProperty.keys()); + delete d_ptr; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtTextEditorFactory::connectPropertyManager(QtTextPropertyManager *manager) +{ + connect(manager, SIGNAL(valueChanged(QtProperty *, const QString &)), + this, SLOT(slotPropertyChanged(QtProperty *, const QString &))); +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +QWidget *QtTextEditorFactory::createEditor(QtTextPropertyManager *manager, + QtProperty *property, QWidget *parent) +{ + + QtTextEditWidget *editor = d_ptr->createEditor(property, parent); + + editor->setValue(manager->value(property)); + + connect(editor, SIGNAL(valueChanged(QString)), this, SLOT(slotSetValue(QString))); + connect(editor, SIGNAL(destroyed(QObject *)), this, SLOT(slotEditorDestroyed(QObject *))); + return editor; +} + +/*! + \internal + + Reimplemented from the QtAbstractEditorFactory class. +*/ +void QtTextEditorFactory::disconnectPropertyManager(QtTextPropertyManager *manager) +{ + disconnect(manager, SIGNAL(valueChanged(QtProperty *, const QString &)), + this, SLOT(slotPropertyChanged(QtProperty *, const QString &))); +} + #if QT_VERSION >= 0x040400 QT_END_NAMESPACE #endif diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qteditorfactory.h b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qteditorfactory.h index 47e7b507f..de79a7a4a 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qteditorfactory.h +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qteditorfactory.h @@ -441,6 +441,28 @@ private: Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QFont &)) }; +class QtTextEditorFactoryPrivate; + +class QT_QTPROPERTYBROWSER_EXPORT QtTextEditorFactory : public QtAbstractEditorFactory +{ + Q_OBJECT +public: + QtTextEditorFactory(QObject *parent = 0); + ~QtTextEditorFactory(); +protected: + void connectPropertyManager(QtTextPropertyManager *manager); + QWidget *createEditor(QtTextPropertyManager *manager, QtProperty *property, + QWidget *parent); + void disconnectPropertyManager(QtTextPropertyManager *manager); +private: + QtTextEditorFactoryPrivate *d_ptr; + Q_DECLARE_PRIVATE(QtTextEditorFactory) + Q_DISABLE_COPY(QtTextEditorFactory) + Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, const QString &)) + Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QString &)) + Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) +}; + #if QT_VERSION >= 0x040400 QT_END_NAMESPACE #endif diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertybrowserutils.cpp b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertybrowserutils.cpp index ce198bfca..0198c3c5f 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertybrowserutils.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertybrowserutils.cpp @@ -91,6 +91,7 @@ #include #include #include +#include #include #include @@ -260,6 +261,7 @@ QString QtPropertyBrowserUtils::fontValueText(const QFont &f) QtBoolEdit::QtBoolEdit(QWidget *parent) : QWidget(parent), m_checkBox(new QCheckBox(this)), + m_defaultButton(new QToolButton(this)), m_textVisible(true) { QHBoxLayout *lt = new QHBoxLayout; @@ -268,6 +270,8 @@ QtBoolEdit::QtBoolEdit(QWidget *parent) : else lt->setContentsMargins(0, 0, 4, 0); lt->addWidget(m_checkBox); + lt->addWidget(m_defaultButton); + m_defaultButton->setEnabled(false); setLayout(lt); connect(m_checkBox, SIGNAL(toggled(bool)), this, SIGNAL(toggled(bool))); setFocusProxy(m_checkBox); diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertybrowserutils_p.h b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertybrowserutils_p.h index dca4b8c37..9fc851f16 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertybrowserutils_p.h +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertybrowserutils_p.h @@ -110,6 +110,7 @@ QT_BEGIN_NAMESPACE class QMouseEvent; class QCheckBox; +class QToolButton; class QLineEdit; class QtCursorDatabase @@ -168,6 +169,7 @@ protected: private: QCheckBox *m_checkBox; + QToolButton *m_defaultButton; bool m_textVisible; }; diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertymanager.cpp b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertymanager.cpp index 20de19786..fe8ea92c9 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertymanager.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertymanager.cpp @@ -99,6 +99,7 @@ #include #include #include +#include #include #include @@ -6457,6 +6458,20 @@ void QtCursorPropertyManager::uninitializeProperty(QtProperty *property) d_ptr->m_values.remove(property); } +QString QtTextPropertyManager::valueText(const QtProperty *property) const +{ + QString text = QtStringPropertyManager::valueText(property); + for (int i = 0; i < text.size(); i++) + { + if (text.at(i) == '\n') + { + QStringRef ret(&text, 0, i); + return ret.toString() + " ..."; + } + } + return text; +} + #if QT_VERSION >= 0x040400 QT_END_NAMESPACE #endif diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertymanager.h b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertymanager.h index 709f2abf7..21fd57d6f 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertymanager.h +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertymanager.h @@ -789,6 +789,16 @@ private: Q_DISABLE_COPY(QtCursorPropertyManager) }; +class QT_QTPROPERTYBROWSER_EXPORT QtTextPropertyManager : public QtStringPropertyManager +{ + Q_OBJECT +public: + QtTextPropertyManager(QObject *parent = 0):QtStringPropertyManager(parent) {} + +protected: + virtual QString valueText(const QtProperty *property) const; +}; + #if QT_VERSION >= 0x040400 QT_END_NAMESPACE #endif From 34b1f12bb838d325fbfed8dd57e442db4edd5d35 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Sun, 5 Feb 2012 02:31:56 +0300 Subject: [PATCH 76/89] Changed: #1302 Added preview properties (except ConstStringArray values). --HG-- branch : gsoc2011-worldeditorqt --- .../plugins/world_editor/primitive_item.cpp | 20 ++ .../src/plugins/world_editor/primitive_item.h | 7 + .../world_editor/property_editor_widget.cpp | 298 +++++++++++++----- .../world_editor/property_editor_widget.h | 20 +- .../world_editor/world_editor_constants.h | 7 +- .../world_editor/world_editor_scene.cpp | 2 +- .../world_editor/world_editor_window.cpp | 25 +- 7 files changed, 289 insertions(+), 90 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.cpp index c0d799401..12d3b994a 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.cpp @@ -173,6 +173,26 @@ WorldEditNode::~WorldEditNode() { } +void WorldEditNode::setContext(const QString &name) +{ + m_context = name; +} + +QString WorldEditNode::context() const +{ + return m_context; +} + +void WorldEditNode::setDataPath(const QString &path) +{ + m_dataPath = path; +} + +QString WorldEditNode::dataPath() const +{ + return m_dataPath; +} + Node::NodeType WorldEditNode::type() const { return WorldEditNodeType; diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h index 7ebf4437f..519b40aaf 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/primitive_item.h @@ -112,9 +112,16 @@ public: WorldEditNode(const QString &name); virtual ~WorldEditNode(); + void setContext(const QString &name); + QString context() const; + void setDataPath(const QString &path); + QString dataPath() const; + virtual NodeType type() const; private: + QString m_context; + QString m_dataPath; }; /* diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.cpp index 7b4224e04..c5e2a2e0d 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.cpp @@ -17,6 +17,7 @@ // Project includes #include "property_editor_widget.h" +#include "world_editor_misc.h" // NeL includes #include @@ -38,15 +39,20 @@ PropertyEditorWidget::PropertyEditorWidget(QWidget *parent) m_variantManager = new QtVariantPropertyManager(this); m_enumManager = new QtEnumPropertyManager(this); + m_stringArrayManager = new QtTextPropertyManager(this); + connect(m_variantManager, SIGNAL(valueChanged(QtProperty *, const QVariant &)), this, SLOT(valueChanged(QtProperty *, const QVariant &))); QtVariantEditorFactory *variantFactory = new QtVariantEditorFactory(this); QtEnumEditorFactory *enumFactory = new QtEnumEditorFactory(this); + QtTextEditorFactory *textFactory = new QtTextEditorFactory(this); + m_ui.treePropertyBrowser->setFactoryForManager(m_variantManager, variantFactory); m_ui.treePropertyBrowser->setFactoryForManager(m_enumManager, enumFactory); + m_ui.treePropertyBrowser->setFactoryForManager(m_stringArrayManager, textFactory); - m_groupManager = new QtGroupPropertyManager(this); + m_groupManager = new QtGroupPropertyManager(this); } PropertyEditorWidget::~PropertyEditorWidget() @@ -58,110 +64,238 @@ void PropertyEditorWidget::clearProperties() m_ui.treePropertyBrowser->clear(); } -void PropertyEditorWidget::updateSelection(const NodeList &selected, const NodeList &deselected) +void PropertyEditorWidget::updateSelection(Node *node) { clearProperties(); + if ((node == 0) || (node->type() != Node::PrimitiveNodeType)) + return; + // The parameter list - std::set parameterList; + std::list parameterList; - for (int i = 0; i < selected.size(); ++i) + PrimitiveNode *primNode = static_cast(node); + const NLLIGO::IPrimitive *primitive = primNode->primitive(); + const NLLIGO::CPrimitiveClass *primClass = primNode->primitiveClass(); + + // Use the class or not ? + if (primClass) { - if (selected.at(i)->type() == Node::RootPrimitiveNodeType) - { - /* - const_cast(_PropDlgLocators[i].Primitive)->removePropertyByName("name"); - const_cast(_PropDlgLocators[i].Primitive)->removePropertyByName("path"); - //TODO faire une fonction dans CWorldDoc pour recup m_strPathName - string name; - getDocument()->getPrimitiveDisplayName(name,_PropDlgLocators[i].getDatabaseIndex()); - string path; - getDocument()->getFilePath(_PropDlgLocators[i].getDatabaseIndex(),path); - - const_cast(_PropDlgLocators[i].Primitive)->addPropertyByName("name",new CPropertyString (name)); - const_cast(_PropDlgLocators[i].Primitive)->addPropertyByName("path",new CPropertyString (path)); - */ - } - - if (selected.at(i)->type() == Node::PrimitiveNodeType) + // For each properties of the class + for (uint p = 0; p < primClass->Parameters.size(); p++) { - PrimitiveNode *node = static_cast(selected.at(i)); - const NLLIGO::IPrimitive *primitive = node->primitive(); - const NLLIGO::CPrimitiveClass *primClass = node->primitiveClass(); - - // Use the class or not ? - if (primClass) + // Is the parameter visible ? + if (primClass->Parameters[p].Visible) { - QtProperty *groupNode; - groupNode = m_groupManager->addProperty(node->data(Qt::DisplayRole).toString()); - m_ui.treePropertyBrowser->addProperty(groupNode); - - // For each properties of the class - for (uint p = 0; p < primClass->Parameters.size(); p++) - { - // Is the parameter visible ? - if (primClass->Parameters[p].Visible) - { - QtProperty *param; - - if (primClass->Parameters[p].Type == NLLIGO::CPrimitiveClass::CParameter::Boolean) - param = m_variantManager->addProperty(QVariant::Bool, primClass->Parameters[p].Name.c_str()); - else if (primClass->Parameters[p].Type == NLLIGO::CPrimitiveClass::CParameter::ConstString) - { - param = m_enumManager->addProperty(primClass->Parameters[p].Name.c_str()); - } - else if (primClass->Parameters[p].Type == NLLIGO::CPrimitiveClass::CParameter::String) - param = m_variantManager->addProperty(QVariant::String, primClass->Parameters[p].Name.c_str()); - else - param = m_variantManager->addProperty(QVariant::String, primClass->Parameters[p].Name.c_str()); - - groupNode->addSubProperty(param); - - parameterList.insert(primClass->Parameters[p]); - } - } + if (primClass->Parameters[p].Name == "name") + parameterList.push_front(primClass->Parameters[p]); + else + parameterList.push_back(primClass->Parameters[p]); } + } + } + else + { + // For each primitive property + uint numProp = primitive->getNumProperty(); + for (uint p = 0; p < numProp; p++) + { + // Get the property + std::string propertyName; + const NLLIGO::IProperty *prop; + nlverify(primitive->getProperty(p, propertyName, prop)); + + // Add a default property + NLLIGO::CPrimitiveClass::CParameter defProp(*prop, propertyName.c_str()); + + if (defProp.Name == "name") + parameterList.push_front(defProp); else - { - // For each primitive property - uint numProp = primitive->getNumProperty(); - for (uint p = 0; p < numProp; p++) - { - // Get the property - std::string propertyName; - const NLLIGO::IProperty *prop; - nlverify(primitive->getProperty (p, propertyName, prop)); - - // Add a default property - NLLIGO::CPrimitiveClass::CParameter defProp(*prop, propertyName.c_str()); - parameterList.insert(defProp); - } - } + parameterList.push_back(defProp); } } // Remove property class - std::set::iterator ite = parameterList.begin (); + std::list::iterator ite = parameterList.begin (); while (ite != parameterList.end ()) { - // Next iterator - std::set::iterator next = ite; + std::list::iterator next = ite; next++; - - // Property name ? if (ite->Name == "class") { - // Remove it - parameterList.erase (ite); + parameterList.erase(ite); } - ite = next; } - // Add the default parameter - NLLIGO::CPrimitiveClass::CParameter defaultParameter; - defaultParameter.Visible = true; - defaultParameter.Filename = false; + QtProperty *groupNode; + groupNode = m_groupManager->addProperty(QString("%1(%2)").arg(node->data(Qt::DisplayRole).toString()).arg(primClass->Name.c_str())); + m_ui.treePropertyBrowser->addProperty(groupNode); + + ite = parameterList.begin (); + while (ite != parameterList.end ()) + { + NLLIGO::CPrimitiveClass::CParameter ¶meter = (*ite); + QtProperty *prop; + NLLIGO::IProperty *ligoProperty; + primitive->getPropertyByName(parameter.Name.c_str(), ligoProperty); + + if (parameter.Type == NLLIGO::CPrimitiveClass::CParameter::ConstString) + prop = addConstStringProperty(ligoProperty, parameter, primitive); + else if (parameter.Type == NLLIGO::CPrimitiveClass::CParameter::String) + prop = addStringProperty(ligoProperty, parameter, primitive); + else if (parameter.Type == NLLIGO::CPrimitiveClass::CParameter::StringArray) + prop = addStringArrayProperty(ligoProperty, parameter, primitive); + else if (parameter.Type == NLLIGO::CPrimitiveClass::CParameter::ConstStringArray) + prop = addConstStringArrayProperty(ligoProperty, parameter, primitive); + else + // hmn? + prop = addBoolProperty(parameter, primitive); + + // Default value ? + if ((ligoProperty == NULL) || (ligoProperty->Default)) + prop->setModified(false); + else + prop->setModified(true); + + bool staticChildSelected = Utils::ligoConfig()->isStaticChild(*primitive); + if (parameter.ReadOnly || (staticChildSelected && (parameter.Name == "name"))) + prop->setEnabled(false); + + groupNode->addSubProperty(prop); + + ite++; + } +} + +QtProperty *PropertyEditorWidget::addBoolProperty(const NLLIGO::IProperty *property, + const NLLIGO::CPrimitiveClass::CParameter ¶meter, + const NLLIGO::IPrimitive *primitive) +{ + std::string value; + std::string name = parameter.Name.c_str(); + primitive->getPropertyByName(name.c_str(), value); + QtVariantProperty *prop = m_variantManager->addProperty(QVariant::Bool, name.c_str()); + // if (Default) + { + //DialogProperties->setDefaultValue (this, value); + prop->setValue(bool((value=="true")?1:0)); + } + return prop; +} + +QtProperty *PropertyEditorWidget::addConstStringProperty(const NLLIGO::IProperty *property, + const NLLIGO::CPrimitiveClass::CParameter ¶meter, + const NLLIGO::IPrimitive *primitive) +{ + std::string context("default"); + + std::string value; + std::string name = parameter.Name.c_str(); + primitive->getPropertyByName(name.c_str(), value); + QtProperty *prop = m_enumManager->addProperty(parameter.Name.c_str()); + + std::map::const_iterator ite = parameter.ComboValues.find(context.c_str()); + + // TODO + //if (ite != parameter.ComboValues.end()) + { + std::vector pathList; + { + ite->second.appendFilePath(pathList); + + /*std::vector relativePrimPaths; + { + std::vector startPrimPath; + for (uint locIndex = 0; locIndex<_PropDlgLocators.size(); locIndex++) + startPrimPath.push_back(_PropDlgLocators[locIndex].Primitive); + + ite->second.getPrimitivesForPrimPath(relativePrimPaths, startPrimPath); + } + ite->second.appendPrimPath(pathList, relativePrimPaths);*/ + } + + if (parameter.SortEntries) + std::sort(pathList.begin(), pathList.end()); + + int currentValue = 0; + QStringList listEnums; + for (size_t i = 0; i < pathList.size(); ++i) + { + listEnums.append(pathList[i].c_str()); + if (value == pathList[i]) + currentValue = i; + } + if (!pathList.empty()) + { + m_enumManager->setEnumNames(prop, listEnums); + m_enumManager->setValue(prop, currentValue); + } + } + return prop; +} + +QtProperty *PropertyEditorWidget::addStringProperty(const NLLIGO::IProperty *property, + const NLLIGO::CPrimitiveClass::CParameter ¶meter, + const NLLIGO::IPrimitive *primitive) +{ + std::string value; + std::string name = parameter.Name.c_str(); + primitive->getPropertyByName(name.c_str(), value); + QtVariantProperty *prop = m_variantManager->addProperty(QVariant::String, parameter.Name.c_str()); + prop->setValue(QString(value.c_str())); + return prop; +} + +QtProperty *PropertyEditorWidget::addStringArrayProperty(const NLLIGO::IProperty *property, + const NLLIGO::CPrimitiveClass::CParameter ¶meter, + const NLLIGO::IPrimitive *primitive) +{ + std::string name = parameter.Name.c_str(); + QtProperty *prop = m_stringArrayManager->addProperty(parameter.Name.c_str()); + + const NLLIGO::IProperty *ligoProperty; + std::vector vectString; + + if (primitive->getPropertyByName (parameter.Name.c_str (), ligoProperty)) + { + const NLLIGO::CPropertyStringArray *const propStringArray = dynamic_cast (ligoProperty); + if (propStringArray) + { + const std::vector &vectString = propStringArray->StringArray; + if (vectString.empty()) + { + //m_stringArrayManager->setValue(prop, "StringArray"); + } + else + { + std::string temp; + for (size_t i = 0; i < vectString.size(); i++) + { + temp += vectString[i]; + if (i != (vectString.size() - 1)) + temp += '\n'; + } + m_stringArrayManager->setValue(prop, temp.c_str()); + prop->setToolTip(temp.c_str()); + } + } + else + { + m_stringArrayManager->setValue(prop, "StringArray :("); + } + } + return prop; +} + +QtProperty *PropertyEditorWidget::addConstStringArrayProperty(const NLLIGO::IProperty *property, + const NLLIGO::CPrimitiveClass::CParameter ¶meter, + const NLLIGO::IPrimitive *primitive) +{ + std::string name = parameter.Name.c_str(); + QtVariantProperty *prop = m_variantManager->addProperty(QVariant::String, parameter.Name.c_str()); + prop->setValue("ConstStringArray"); + return prop; } } /* namespace WorldEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.h index 3a2506def..a4ccf9d5f 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.h @@ -51,14 +51,30 @@ public: public Q_SLOTS: void clearProperties(); - /// Update of selections - void updateSelection(const NodeList &selected, const NodeList &deselected); + /// Update of selections + void updateSelection(Node *node); private: + QtProperty *addBoolProperty(const NLLIGO::IProperty *property, + const NLLIGO::CPrimitiveClass::CParameter ¶meter, + const NLLIGO::IPrimitive *primitive); + QtProperty *addConstStringProperty(const NLLIGO::IProperty *property, + const NLLIGO::CPrimitiveClass::CParameter ¶meter, + const NLLIGO::IPrimitive *primitive); + QtProperty *addStringProperty(const NLLIGO::IProperty *property, + const NLLIGO::CPrimitiveClass::CParameter ¶meter, + const NLLIGO::IPrimitive *primitive); + QtProperty *addStringArrayProperty(const NLLIGO::IProperty *property, + const NLLIGO::CPrimitiveClass::CParameter ¶meter, + const NLLIGO::IPrimitive *primitive); + QtProperty *addConstStringArrayProperty(const NLLIGO::IProperty *property, + const NLLIGO::CPrimitiveClass::CParameter ¶meter, + const NLLIGO::IPrimitive *primitive); QtVariantPropertyManager *m_variantManager; QtEnumPropertyManager *m_enumManager; QtGroupPropertyManager *m_groupManager; + QtTextPropertyManager *m_stringArrayManager; Ui::PropertyEditorWidget m_ui; }; /* PropertyEditorWidget */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_constants.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_constants.h index d0617373e..7ca698697 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_constants.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_constants.h @@ -31,9 +31,14 @@ const int GRAPHICS_DATA_NEL3D = USER_TYPE + 4; const int PRIMITIVE_IS_MODIFIED = USER_TYPE + 5; const int PRIMITIVE_FILE_IS_CREATED = USER_TYPE + 6; const int PRIMITIVE_IS_VISIBLE = USER_TYPE + 7; +const int PRIMITIVE_IS_ENABLD = USER_TYPE + 8; +const int PRIMITIVE_FILE_NAME = USER_TYPE + 9; +const int PRIMITIVE_NON_REMOVABLE = USER_TYPE + 10; +const int ROOT_PRIMITIVE_CONTEXT = USER_TYPE + 20; +const int ROOT_PRIMITIVE_DATA_DIRECTORY = USER_TYPE + 21; //properties editor -const char *const DIFFERENT_VALUE_STRING = ""; +const char *const DIFFERENT_VALUE_STRING = ""; const char *const DIFFERENT_VALUE_MULTI_STRING = ""; //settings diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp index 9922daaf7..c58102ac2 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp @@ -274,7 +274,7 @@ void WorldEditorScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) else m_editedSelectedItems = false; } - // Update render + // Update render (drawing selection area when enabled multiple selection mode) update(); } diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp index 30173b9d9..382b356c0 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_window.cpp @@ -275,8 +275,16 @@ void WorldEditorWindow::updateSelection(const QItemSelection &selected, const QI nodesDeselected.push_back(node); } - // TODO: update property editor - m_ui.propertyEditWidget->updateSelection(nodesSelected, nodesDeselected); + // update property editor + if (nodesSelected.size() > 0) + { + // only single selection + m_ui.propertyEditWidget->updateSelection(nodesSelected.at(0)); + } + else + { + m_ui.propertyEditWidget->clearProperties(); + } QList itemSelected; Q_FOREACH(Node *node, nodesSelected) @@ -320,8 +328,17 @@ void WorldEditorWindow::selectedItemsInScene(const QList &selec selectionModel->select(itemSelection, QItemSelectionModel::Select); - // TODO: update property editor - // ... + // update property editor + if (!selected.isEmpty()) + { + // only single selection + Node *node = qvariant_cast(selected.at(0)->data(Constants::WORLD_EDITOR_NODE)); + m_ui.propertyEditWidget->updateSelection(node); + } + else + { + m_ui.propertyEditWidget->clearProperties(); + } connect(m_ui.treePrimitivesView->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this, SLOT(updateSelection(QItemSelection, QItemSelection))); From d6731657c1fcf760e15e4d32695c08675fa9c3a5 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Mon, 23 Apr 2012 19:20:09 +0300 Subject: [PATCH 77/89] Changed: #1302 Fixed undo/redo bug (moving primitives). --HG-- branch : gsoc2011-worldeditorqt --- .../src/plugins/landscape_editor/pixmap_database.cpp | 1 + .../src/plugins/world_editor/property_editor_widget.cpp | 2 +- .../src/plugins/world_editor/world_editor_scene.cpp | 4 +++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.cpp index 0156f5a53..15f8760be 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/pixmap_database.cpp @@ -96,6 +96,7 @@ bool PixmapDatabase::loadPixmaps(const QString &zonePath, NLLIGO::CZoneBank &zon painter.end(); delete pixmap; m_pixmapMap.insert(zonePixmapName, emptyPixmap); + nlwarning(QString("not found " + zonePath + zonePixmapName + ".png").toStdString().c_str()); } // All pixmaps must be have same size else if (pixmap->width() != sizeX * m_textureSize) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.cpp index c5e2a2e0d..990f4935d 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.cpp @@ -150,7 +150,7 @@ void PropertyEditorWidget::updateSelection(Node *node) prop = addConstStringArrayProperty(ligoProperty, parameter, primitive); else // hmn? - prop = addBoolProperty(parameter, primitive); + prop = addBoolProperty(ligoProperty, parameter, primitive); // Default value ? if ((ligoProperty == NULL) || (ligoProperty->Default)) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp index c58102ac2..e24ef50e7 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp @@ -227,6 +227,7 @@ void WorldEditorScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) } m_editedSelectedItems = false; + m_offset = QPointF(0, 0); m_angle = 0; m_scaleFactor = QPointF(1.0, 1.0); @@ -516,7 +517,8 @@ void WorldEditorScene::checkUndoPointsMode() void WorldEditorScene::updateWorldItemsMove(QGraphicsSceneMouseEvent *mouseEvent) { - QPointF offset(mouseEvent->scenePos() - mouseEvent->lastScenePos()); + QPointF offset = mouseEvent->scenePos() - mouseEvent->lastScenePos(); + m_offset += offset; if (m_pointsMode) Q_FOREACH(QGraphicsItem *item, m_selectedPoints) { From 5c4f7063910614f3915aa56d834e434cf178a8ac Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Sun, 10 Jun 2012 16:56:45 +0300 Subject: [PATCH 78/89] Changed: #1302 Correct fill properties(ConstStringValue) with *both* contexts if the current context is not default and is valid. --HG-- branch : gsoc2011-worldeditorqt --- .../world_editor/property_editor_widget.cpp | 98 ++++++++++++------- 1 file changed, 63 insertions(+), 35 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.cpp index 990f4935d..c3b9a3ba6 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.cpp @@ -132,12 +132,12 @@ void PropertyEditorWidget::updateSelection(Node *node) groupNode = m_groupManager->addProperty(QString("%1(%2)").arg(node->data(Qt::DisplayRole).toString()).arg(primClass->Name.c_str())); m_ui.treePropertyBrowser->addProperty(groupNode); - ite = parameterList.begin (); - while (ite != parameterList.end ()) + ite = parameterList.begin(); + while (ite != parameterList.end()) { NLLIGO::CPrimitiveClass::CParameter ¶meter = (*ite); QtProperty *prop; - NLLIGO::IProperty *ligoProperty; + NLLIGO::IProperty *ligoProperty = 0; primitive->getPropertyByName(parameter.Name.c_str(), ligoProperty); if (parameter.Type == NLLIGO::CPrimitiveClass::CParameter::ConstString) @@ -188,50 +188,81 @@ QtProperty *PropertyEditorWidget::addConstStringProperty(const NLLIGO::IProperty const NLLIGO::CPrimitiveClass::CParameter ¶meter, const NLLIGO::IPrimitive *primitive) { - std::string context("default"); + // TODO: get context value from dialog + std::string context("jungle"); + std::string defaultContext("default"); std::string value; std::string name = parameter.Name.c_str(); + + // Get current value primitive->getPropertyByName(name.c_str(), value); + + // Create qt property QtProperty *prop = m_enumManager->addProperty(parameter.Name.c_str()); - std::map::const_iterator ite = parameter.ComboValues.find(context.c_str()); + std::vector listContext; + + if (context != defaultContext) + listContext.push_back(context); + listContext.push_back(defaultContext); - // TODO - //if (ite != parameter.ComboValues.end()) + QStringList listEnums; + + // Correct fill properties with *both* contexts if the current context is not default and is valid. + for (size_t j = 0; j < listContext.size(); j++) { - std::vector pathList; - { - ite->second.appendFilePath(pathList); + std::map::const_iterator ite = parameter.ComboValues.find(listContext[j].c_str()); - /*std::vector relativePrimPaths; + if (ite != parameter.ComboValues.end()) + { + std::vector pathList; { - std::vector startPrimPath; - for (uint locIndex = 0; locIndex<_PropDlgLocators.size(); locIndex++) - startPrimPath.push_back(_PropDlgLocators[locIndex].Primitive); + ite->second.appendFilePath(pathList); - ite->second.getPrimitivesForPrimPath(relativePrimPaths, startPrimPath); + // TODO: what is it? + /*std::vector relativePrimPaths; + { + std::vector startPrimPath; + for (uint locIndex = 0; locIndex<_PropDlgLocators.size(); locIndex++) + startPrimPath.push_back(_PropDlgLocators[locIndex].Primitive); + + ite->second.getPrimitivesForPrimPath(relativePrimPaths, startPrimPath); + } + ite->second.appendPrimPath(pathList, relativePrimPaths);*/ } - ite->second.appendPrimPath(pathList, relativePrimPaths);*/ - } - if (parameter.SortEntries) - std::sort(pathList.begin(), pathList.end()); + if (parameter.SortEntries) + std::sort(pathList.begin(), pathList.end()); - int currentValue = 0; - QStringList listEnums; - for (size_t i = 0; i < pathList.size(); ++i) - { - listEnums.append(pathList[i].c_str()); - if (value == pathList[i]) - currentValue = i; + for (size_t i = 0; i < pathList.size(); ++i) + listEnums.append(pathList[i].c_str()); } - if (!pathList.empty()) + } + + if (listEnums.isEmpty()) + { + listEnums << tr("WRN: Check leveldesign!"); + m_enumManager->setEnumNames(prop, listEnums); + m_enumManager->setValue(prop, 0); + prop->setEnabled(false); + } + else + { + // Fill qt property + m_enumManager->setEnumNames(prop, listEnums); + + // Find index of current value + for (int i = 0; i < listEnums.size(); i++) { - m_enumManager->setEnumNames(prop, listEnums); - m_enumManager->setValue(prop, currentValue); + if (value == listEnums[i].toStdString()) + { + m_enumManager->setValue(prop, i); + break; + } } } + return prop; } @@ -263,11 +294,7 @@ QtProperty *PropertyEditorWidget::addStringArrayProperty(const NLLIGO::IProperty if (propStringArray) { const std::vector &vectString = propStringArray->StringArray; - if (vectString.empty()) - { - //m_stringArrayManager->setValue(prop, "StringArray"); - } - else + if (!vectString.empty()) { std::string temp; for (size_t i = 0; i < vectString.size(); i++) @@ -294,7 +321,8 @@ QtProperty *PropertyEditorWidget::addConstStringArrayProperty(const NLLIGO::IPro { std::string name = parameter.Name.c_str(); QtVariantProperty *prop = m_variantManager->addProperty(QVariant::String, parameter.Name.c_str()); - prop->setValue("ConstStringArray"); + prop->setValue("TODO: ConstStringArray"); + prop->setEnabled(false); return prop; } From a175d04f860b881a763edf82d158ece6e4be73a6 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Sun, 10 Jun 2012 18:27:47 +0300 Subject: [PATCH 79/89] Changed: #1302 Fixed undo/redo bug (moving primitives). --HG-- branch : gsoc2011-worldeditorqt --- .../src/plugins/world_editor/world_editor_scene.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp index e24ef50e7..678b361fe 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_scene.cpp @@ -467,7 +467,7 @@ void WorldEditorScene::updatePickSelectionPoints(const QPointF &point) void WorldEditorScene::checkUndo() { - if (m_editedSelectedItems) + if (m_editedSelectedItems && (!isEnabledEditPoints())) { switch (m_mode) { From b5bea9013f47f986d8ad395147cd055e690f19ad Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Sun, 10 Jun 2012 21:15:22 +0300 Subject: [PATCH 80/89] Changed: #1302 Added signal 'reset bool property' for returning to default value --HG-- branch : gsoc2011-worldeditorqt --- .../images/resetproperty.png | Bin 0 -> 169 bytes .../qtpropertybrowser/qteditorfactory.cpp | 29 ++++++++++++++++-- .../qtpropertybrowser/qteditorfactory.h | 1 + .../qtpropertybrowser/qtpropertybrowser.qrc | 1 + .../qtpropertybrowserutils.cpp | 13 +++++++- .../qtpropertybrowserutils_p.h | 2 ++ .../qtpropertybrowser/qtpropertymanager.cpp | 5 +++ .../qtpropertybrowser/qtpropertymanager.h | 4 +++ 8 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/resetproperty.png diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/resetproperty.png b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/resetproperty.png new file mode 100644 index 0000000000000000000000000000000000000000..9048252ec2a51e7ee3461b72ba31fcabb2f10027 GIT binary patch literal 169 zcmeAS@N?(olHy`uVBq!ia0vp^>_E)M!VDz;D$H~RQtAOdA+G=b|DVXfKoI@;pQ;7a z!c!9D7tA1OVDFM#)bRFI`d!AXvO1u+s;7%%2#0KP!Un;Fgaq5gCk{*~e&)l-9KQS# jBO6=3qr$;M$qWpMPuN;S?ziRvH86O(`njxgN@xNAXMir1 literal 0 HcmV?d00001 diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qteditorfactory.cpp b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qteditorfactory.cpp index 3a1e874eb..c1a10ff0a 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qteditorfactory.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qteditorfactory.cpp @@ -659,6 +659,7 @@ class QtCheckBoxFactoryPrivate : public EditorFactoryPrivate public: void slotPropertyChanged(QtProperty *property, bool value); void slotSetValue(bool value); + void slotReset(); }; void QtCheckBoxFactoryPrivate::slotPropertyChanged(QtProperty *property, bool value) @@ -669,6 +670,7 @@ void QtCheckBoxFactoryPrivate::slotPropertyChanged(QtProperty *property, bool va QListIterator itEditor(m_createdEditors[property]); while (itEditor.hasNext()) { QtBoolEdit *editor = itEditor.next(); + editor->setStateResetButton(property->isModified()); editor->blockCheckBoxSignals(true); editor->setChecked(value); editor->blockCheckBoxSignals(false); @@ -691,6 +693,22 @@ void QtCheckBoxFactoryPrivate::slotSetValue(bool value) } } +void QtCheckBoxFactoryPrivate::slotReset() +{ + QObject *object = q_ptr->sender(); + + const QMap::ConstIterator ecend = m_editorToProperty.constEnd(); + for (QMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor) + if (itEditor.key() == object) { + QtProperty *property = itEditor.value(); + QtBoolPropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + manager->setResetProperty(property); + return; + } +} + /*! \class QtCheckBoxFactory @@ -740,8 +758,10 @@ QWidget *QtCheckBoxFactory::createEditor(QtBoolPropertyManager *manager, QtPrope QWidget *parent) { QtBoolEdit *editor = d_ptr->createEditor(property, parent); + editor->setStateResetButton(property->isModified()); editor->setChecked(manager->value(property)); + connect(editor, SIGNAL(resetProperty()), this, SLOT(slotReset())); connect(editor, SIGNAL(toggled(bool)), this, SLOT(slotSetValue(bool))); connect(editor, SIGNAL(destroyed(QObject *)), this, SLOT(slotEditorDestroyed(QObject *))); @@ -2645,10 +2665,15 @@ QtTextEditWidget::QtTextEditWidget(QWidget *parent) : m_button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Ignored); m_button->setFixedWidth(20); - setFocusProxy(m_button); - setFocusPolicy(m_button->focusPolicy()); m_button->setText(tr("...")); m_button->installEventFilter(this); + + setFocusProxy(m_button); + setFocusPolicy(m_button->focusPolicy()); + + m_defaultButton->setIcon(QIcon(":/trolltech/qtpropertybrowser/images/resetproperty.png")); + m_defaultButton->setMaximumWidth(16); + connect(m_button, SIGNAL(clicked()), this, SLOT(buttonClicked())); lt->addWidget(m_button); lt->addWidget(m_defaultButton); diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qteditorfactory.h b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qteditorfactory.h index de79a7a4a..58f64b2af 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qteditorfactory.h +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qteditorfactory.h @@ -186,6 +186,7 @@ private: Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, bool)) Q_PRIVATE_SLOT(d_func(), void slotSetValue(bool)) Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) + Q_PRIVATE_SLOT(d_func(), void slotReset()) }; class QtDoubleSpinBoxFactoryPrivate; diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertybrowser.qrc b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertybrowser.qrc index 4f91ab782..50c2479f2 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertybrowser.qrc +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertybrowser.qrc @@ -18,6 +18,7 @@ images/cursor-vsplit.png images/cursor-wait.png images/cursor-whatsthis.png + images/resetproperty.png diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertybrowserutils.cpp b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertybrowserutils.cpp index 0198c3c5f..9b482a569 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertybrowserutils.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertybrowserutils.cpp @@ -264,6 +264,10 @@ QtBoolEdit::QtBoolEdit(QWidget *parent) : m_defaultButton(new QToolButton(this)), m_textVisible(true) { + m_defaultButton->setIcon(QIcon(":/trolltech/qtpropertybrowser/images/resetproperty.png")); + m_defaultButton->setMaximumWidth(16); + m_defaultButton->setEnabled(false); + QHBoxLayout *lt = new QHBoxLayout; if (QApplication::layoutDirection() == Qt::LeftToRight) lt->setContentsMargins(4, 0, 0, 0); @@ -271,9 +275,11 @@ QtBoolEdit::QtBoolEdit(QWidget *parent) : lt->setContentsMargins(0, 0, 4, 0); lt->addWidget(m_checkBox); lt->addWidget(m_defaultButton); - m_defaultButton->setEnabled(false); setLayout(lt); + connect(m_checkBox, SIGNAL(toggled(bool)), this, SIGNAL(toggled(bool))); + connect(m_defaultButton, SIGNAL(clicked()), this, SIGNAL(resetProperty())); + setFocusProxy(m_checkBox); m_checkBox->setText(QString()); } @@ -297,6 +303,11 @@ void QtBoolEdit::setCheckState(Qt::CheckState state) m_checkBox->setCheckState(state); } +void QtBoolEdit::setStateResetButton(bool enabled) +{ + m_defaultButton->setEnabled(enabled); +} + bool QtBoolEdit::isChecked() const { return m_checkBox->isChecked(); diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertybrowserutils_p.h b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertybrowserutils_p.h index 9fc851f16..66156c5d4 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertybrowserutils_p.h +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertybrowserutils_p.h @@ -155,6 +155,7 @@ public: Qt::CheckState checkState() const; void setCheckState(Qt::CheckState state); + void setStateResetButton(bool enabled); bool isChecked() const; void setChecked(bool c); @@ -163,6 +164,7 @@ public: Q_SIGNALS: void toggled(bool); + void resetProperty(); protected: void mousePressEvent(QMouseEvent * event); diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertymanager.cpp b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertymanager.cpp index fe8ea92c9..6b2d24c80 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertymanager.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertymanager.cpp @@ -1588,6 +1588,11 @@ void QtBoolPropertyManager::setValue(QtProperty *property, bool val) property, val); } +void QtBoolPropertyManager::setResetProperty(QtProperty *property) +{ + emit resetProperty(property); +} + /*! \reimp */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertymanager.h b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertymanager.h index 21fd57d6f..958b22dc8 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertymanager.h +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertymanager.h @@ -160,8 +160,12 @@ public: public Q_SLOTS: void setValue(QtProperty *property, bool val); + void setResetProperty(QtProperty *property); + Q_SIGNALS: void valueChanged(QtProperty *property, bool val); + void resetProperty(QtProperty *property); + protected: QString valueText(const QtProperty *property) const; QIcon valueIcon(const QtProperty *property) const; From 1f81694b82c4e33ad3431e32e84b8b7f1c9c8db2 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Sun, 10 Jun 2012 22:13:19 +0300 Subject: [PATCH 81/89] Changed: #1302 Added signal 'reset text property' for returning to default value --HG-- branch : gsoc2011-worldeditorqt --- .../qtpropertybrowser/qteditorfactory.cpp | 39 +++++++++++++++++-- .../qtpropertybrowser/qteditorfactory.h | 1 + .../qtpropertybrowser/qtpropertybrowser.cpp | 5 +++ .../qtpropertybrowser/qtpropertybrowser.h | 2 + .../qtpropertybrowser/qtpropertymanager.cpp | 5 --- .../qtpropertybrowser/qtpropertymanager.h | 2 - 6 files changed, 43 insertions(+), 11 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qteditorfactory.cpp b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qteditorfactory.cpp index c1a10ff0a..9331959b9 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qteditorfactory.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qteditorfactory.cpp @@ -704,7 +704,7 @@ void QtCheckBoxFactoryPrivate::slotReset() QtBoolPropertyManager *manager = q_ptr->propertyManager(property); if (!manager) return; - manager->setResetProperty(property); + manager->emitResetProperty(property); return; } } @@ -2638,12 +2638,14 @@ public: public Q_SLOTS: void setValue(const QString &value); + void setStateResetButton(bool enabled); private Q_SLOTS: void buttonClicked(); Q_SIGNALS: void valueChanged(const QString &value); + void resetProperty(); private: QLineEdit *m_lineEdit; @@ -2675,6 +2677,7 @@ QtTextEditWidget::QtTextEditWidget(QWidget *parent) : m_defaultButton->setMaximumWidth(16); connect(m_button, SIGNAL(clicked()), this, SLOT(buttonClicked())); + connect(m_defaultButton, SIGNAL(clicked()), this, SIGNAL(resetProperty())); lt->addWidget(m_button); lt->addWidget(m_defaultButton); m_defaultButton->setEnabled(false); @@ -2686,6 +2689,11 @@ void QtTextEditWidget::setValue(const QString &value) m_lineEdit->setText(value); } +void QtTextEditWidget::setStateResetButton(bool enabled) +{ + m_defaultButton->setEnabled(enabled); +} + void QtTextEditWidget::buttonClicked() { QGridLayout *gridLayout; @@ -2761,6 +2769,7 @@ public: void slotPropertyChanged(QtProperty *property, const QString &value); void slotSetValue(const QString &value); + void slotResetProperty(); }; void QtTextEditorFactoryPrivate::slotPropertyChanged(QtProperty *property, @@ -2772,7 +2781,11 @@ void QtTextEditorFactoryPrivate::slotPropertyChanged(QtProperty *property, QListIterator itEditor(it.value()); while (itEditor.hasNext()) - itEditor.next()->setValue(value); + { + QtTextEditWidget *editor = itEditor.next(); + editor->setValue(value); + editor->setStateResetButton(property->isModified()); + } } void QtTextEditorFactoryPrivate::slotSetValue(const QString &value) @@ -2789,6 +2802,22 @@ void QtTextEditorFactoryPrivate::slotSetValue(const QString &value) return; } } + +void QtTextEditorFactoryPrivate::slotResetProperty() +{ + QObject *object = q_ptr->sender(); + const EditorToPropertyMap::ConstIterator ecend = m_editorToProperty.constEnd(); + for (EditorToPropertyMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor) + if (itEditor.key() == object) { + QtProperty *property = itEditor.value(); + QtTextPropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + manager->emitResetProperty(property); + return; + } +} + /*! \class QtTextEditFactory @@ -2841,8 +2870,10 @@ QWidget *QtTextEditorFactory::createEditor(QtTextPropertyManager *manager, QtTextEditWidget *editor = d_ptr->createEditor(property, parent); editor->setValue(manager->value(property)); - - connect(editor, SIGNAL(valueChanged(QString)), this, SLOT(slotSetValue(QString))); + editor->setStateResetButton(property->isModified()); + + connect(editor, SIGNAL(resetProperty()), this, SLOT(slotResetProperty())); + connect(editor, SIGNAL(valueChanged(QString)), this, SLOT(slotSetValue(QString))); connect(editor, SIGNAL(destroyed(QObject *)), this, SLOT(slotEditorDestroyed(QObject *))); return editor; } diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qteditorfactory.h b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qteditorfactory.h index 58f64b2af..38489684e 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qteditorfactory.h +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qteditorfactory.h @@ -462,6 +462,7 @@ private: Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, const QString &)) Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QString &)) Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) + Q_PRIVATE_SLOT(d_func(), void slotResetProperty()) }; #if QT_VERSION >= 0x040400 diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertybrowser.cpp b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertybrowser.cpp index e8c103d9b..9b7d98b09 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertybrowser.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertybrowser.cpp @@ -808,6 +808,11 @@ QtProperty *QtAbstractPropertyManager::addProperty(const QString &name) return property; } +void QtAbstractPropertyManager::emitResetProperty(QtProperty *property) +{ + emit resetProperty(property); +} + /*! Creates a property. diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertybrowser.h b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertybrowser.h index 35b7ac0f8..5b63d3917 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertybrowser.h +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertybrowser.h @@ -170,6 +170,7 @@ public: void clear() const; QtProperty *addProperty(const QString &name = QString()); + void emitResetProperty(QtProperty *property); Q_SIGNALS: void propertyInserted(QtProperty *property, @@ -177,6 +178,7 @@ Q_SIGNALS: void propertyChanged(QtProperty *property); void propertyRemoved(QtProperty *property, QtProperty *parent); void propertyDestroyed(QtProperty *property); + void resetProperty(QtProperty *property); protected: virtual bool hasValue(const QtProperty *property) const; virtual QIcon valueIcon(const QtProperty *property) const; diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertymanager.cpp b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertymanager.cpp index 6b2d24c80..fe8ea92c9 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertymanager.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertymanager.cpp @@ -1588,11 +1588,6 @@ void QtBoolPropertyManager::setValue(QtProperty *property, bool val) property, val); } -void QtBoolPropertyManager::setResetProperty(QtProperty *property) -{ - emit resetProperty(property); -} - /*! \reimp */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertymanager.h b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertymanager.h index 958b22dc8..a19dd6e03 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertymanager.h +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qtpropertymanager.h @@ -160,11 +160,9 @@ public: public Q_SLOTS: void setValue(QtProperty *property, bool val); - void setResetProperty(QtProperty *property); Q_SIGNALS: void valueChanged(QtProperty *property, bool val); - void resetProperty(QtProperty *property); protected: QString valueText(const QtProperty *property) const; From 4f3999168e1e6ac454b9f912476822b58e6b06ac Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Sun, 10 Jun 2012 23:40:48 +0300 Subject: [PATCH 82/89] Changed: #1302 Added signal 'reset enum property' for returning to default value --HG-- branch : gsoc2011-worldeditorqt --- .../qtpropertybrowser/qteditorfactory.cpp | 148 +++++++++++++++--- .../qtpropertybrowser/qteditorfactory.h | 3 +- 2 files changed, 124 insertions(+), 27 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qteditorfactory.cpp b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qteditorfactory.cpp index 9331959b9..e5ac11f81 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qteditorfactory.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qteditorfactory.cpp @@ -659,7 +659,7 @@ class QtCheckBoxFactoryPrivate : public EditorFactoryPrivate public: void slotPropertyChanged(QtProperty *property, bool value); void slotSetValue(bool value); - void slotReset(); + void slotResetProperty(); }; void QtCheckBoxFactoryPrivate::slotPropertyChanged(QtProperty *property, bool value) @@ -693,7 +693,7 @@ void QtCheckBoxFactoryPrivate::slotSetValue(bool value) } } -void QtCheckBoxFactoryPrivate::slotReset() +void QtCheckBoxFactoryPrivate::slotResetProperty() { QObject *object = q_ptr->sender(); @@ -761,7 +761,7 @@ QWidget *QtCheckBoxFactory::createEditor(QtBoolPropertyManager *manager, QtPrope editor->setStateResetButton(property->isModified()); editor->setChecked(manager->value(property)); - connect(editor, SIGNAL(resetProperty()), this, SLOT(slotReset())); + connect(editor, SIGNAL(resetProperty()), this, SLOT(slotResetProperty())); connect(editor, SIGNAL(toggled(bool)), this, SLOT(slotSetValue(bool))); connect(editor, SIGNAL(destroyed(QObject *)), this, SLOT(slotEditorDestroyed(QObject *))); @@ -1880,9 +1880,87 @@ void QtCharEditorFactory::disconnectPropertyManager(QtCharPropertyManager *manag this, SLOT(slotPropertyChanged(QtProperty *, const QChar &))); } + +class QtEnumEditWidget : public QWidget { + Q_OBJECT + +public: + QtEnumEditWidget(QWidget *parent); + + bool blockComboBoxSignals(bool block); + void addItems(const QStringList &texts); + void clearComboBox(); + void setItemIcon(int index, const QIcon &icon); + +public Q_SLOTS: + void setValue(int value); + void setStateResetButton(bool enabled); + +Q_SIGNALS: + void valueChanged(int value); + void resetProperty(); + +private: + QComboBox *m_comboBox; + QToolButton *m_defaultButton; +}; + +QtEnumEditWidget::QtEnumEditWidget(QWidget *parent) : + QWidget(parent), + m_comboBox(new QComboBox), + m_defaultButton(new QToolButton) +{ + m_comboBox->view()->setTextElideMode(Qt::ElideRight); + + QHBoxLayout *lt = new QHBoxLayout(this); + lt->setContentsMargins(0, 0, 0, 0); + lt->setSpacing(0); + lt->addWidget(m_comboBox); + + m_defaultButton->setIcon(QIcon(":/trolltech/qtpropertybrowser/images/resetproperty.png")); + m_defaultButton->setMaximumWidth(16); + + connect(m_comboBox, SIGNAL(currentIndexChanged(int)), this, SIGNAL(valueChanged(int))); + connect(m_defaultButton, SIGNAL(clicked()), this, SIGNAL(resetProperty())); + lt->addWidget(m_defaultButton); + m_defaultButton->setEnabled(false); + setFocusProxy(m_comboBox); +} + +void QtEnumEditWidget::setValue(int value) +{ + if (m_comboBox->currentIndex() != value) + m_comboBox->setCurrentIndex(value); +} + +void QtEnumEditWidget::setStateResetButton(bool enabled) +{ + m_defaultButton->setEnabled(enabled); +} + +bool QtEnumEditWidget::blockComboBoxSignals(bool block) +{ + return m_comboBox->blockSignals(block); +} + +void QtEnumEditWidget::addItems(const QStringList &texts) +{ + m_comboBox->addItems(texts); +} + +void QtEnumEditWidget::clearComboBox() +{ + m_comboBox->clear(); +} + +void QtEnumEditWidget::setItemIcon(int index, const QIcon &icon) +{ + m_comboBox->setItemIcon(index, icon); +} + // QtEnumEditorFactory -class QtEnumEditorFactoryPrivate : public EditorFactoryPrivate +class QtEnumEditorFactoryPrivate : public EditorFactoryPrivate { QtEnumEditorFactory *q_ptr; Q_DECLARE_PUBLIC(QtEnumEditorFactory) @@ -1892,19 +1970,36 @@ public: void slotEnumNamesChanged(QtProperty *property, const QStringList &); void slotEnumIconsChanged(QtProperty *property, const QMap &); void slotSetValue(int value); + void slotResetProperty(); }; +void QtEnumEditorFactoryPrivate::slotResetProperty() +{ + QObject *object = q_ptr->sender(); + const EditorToPropertyMap::ConstIterator ecend = m_editorToProperty.constEnd(); + for (EditorToPropertyMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor) + if (itEditor.key() == object) { + QtProperty *property = itEditor.value(); + QtEnumPropertyManager *manager = q_ptr->propertyManager(property); + if (!manager) + return; + manager->emitResetProperty(property); + return; + } +} + void QtEnumEditorFactoryPrivate::slotPropertyChanged(QtProperty *property, int value) { if (!m_createdEditors.contains(property)) return; - QListIterator itEditor(m_createdEditors[property]); + QListIterator itEditor(m_createdEditors[property]); while (itEditor.hasNext()) { - QComboBox *editor = itEditor.next(); - editor->blockSignals(true); - editor->setCurrentIndex(value); - editor->blockSignals(false); + QtEnumEditWidget *editor = itEditor.next(); + editor->setStateResetButton(property->isModified()); + editor->blockComboBoxSignals(true); + editor->setValue(value); + editor->blockComboBoxSignals(false); } } @@ -1920,17 +2015,17 @@ void QtEnumEditorFactoryPrivate::slotEnumNamesChanged(QtProperty *property, QMap enumIcons = manager->enumIcons(property); - QListIterator itEditor(m_createdEditors[property]); + QListIterator itEditor(m_createdEditors[property]); while (itEditor.hasNext()) { - QComboBox *editor = itEditor.next(); - editor->blockSignals(true); - editor->clear(); + QtEnumEditWidget *editor = itEditor.next(); + editor->blockComboBoxSignals(true); + editor->clearComboBox(); editor->addItems(enumNames); const int nameCount = enumNames.count(); for (int i = 0; i < nameCount; i++) editor->setItemIcon(i, enumIcons.value(i)); - editor->setCurrentIndex(manager->value(property)); - editor->blockSignals(false); + editor->setValue(manager->value(property)); + editor->blockComboBoxSignals(false); } } @@ -1945,23 +2040,23 @@ void QtEnumEditorFactoryPrivate::slotEnumIconsChanged(QtProperty *property, return; const QStringList enumNames = manager->enumNames(property); - QListIterator itEditor(m_createdEditors[property]); + QListIterator itEditor(m_createdEditors[property]); while (itEditor.hasNext()) { - QComboBox *editor = itEditor.next(); - editor->blockSignals(true); + QtEnumEditWidget *editor = itEditor.next(); + editor->blockComboBoxSignals(true); const int nameCount = enumNames.count(); for (int i = 0; i < nameCount; i++) editor->setItemIcon(i, enumIcons.value(i)); - editor->setCurrentIndex(manager->value(property)); - editor->blockSignals(false); + editor->setValue(manager->value(property)); + editor->blockComboBoxSignals(false); } } void QtEnumEditorFactoryPrivate::slotSetValue(int value) { QObject *object = q_ptr->sender(); - const QMap::ConstIterator ecend = m_editorToProperty.constEnd(); - for (QMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor) + const QMap::ConstIterator ecend = m_editorToProperty.constEnd(); + for (QMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor) if (itEditor.key() == object) { QtProperty *property = itEditor.value(); QtEnumPropertyManager *manager = q_ptr->propertyManager(property); @@ -2022,18 +2117,19 @@ void QtEnumEditorFactory::connectPropertyManager(QtEnumPropertyManager *manager) QWidget *QtEnumEditorFactory::createEditor(QtEnumPropertyManager *manager, QtProperty *property, QWidget *parent) { - QComboBox *editor = d_ptr->createEditor(property, parent); + QtEnumEditWidget *editor = d_ptr->createEditor(property, parent); editor->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed); - editor->view()->setTextElideMode(Qt::ElideRight); QStringList enumNames = manager->enumNames(property); editor->addItems(enumNames); QMap enumIcons = manager->enumIcons(property); const int enumNamesCount = enumNames.count(); for (int i = 0; i < enumNamesCount; i++) editor->setItemIcon(i, enumIcons.value(i)); - editor->setCurrentIndex(manager->value(property)); + editor->setValue(manager->value(property)); + editor->setStateResetButton(property->isModified()); - connect(editor, SIGNAL(currentIndexChanged(int)), this, SLOT(slotSetValue(int))); + connect(editor, SIGNAL(resetProperty()), this, SLOT(slotResetProperty())); + connect(editor, SIGNAL(valueChanged(int)), this, SLOT(slotSetValue(int))); connect(editor, SIGNAL(destroyed(QObject *)), this, SLOT(slotEditorDestroyed(QObject *))); return editor; diff --git a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qteditorfactory.h b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qteditorfactory.h index 38489684e..fe47d5f16 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qteditorfactory.h +++ b/code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/qteditorfactory.h @@ -186,7 +186,7 @@ private: Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, bool)) Q_PRIVATE_SLOT(d_func(), void slotSetValue(bool)) Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) - Q_PRIVATE_SLOT(d_func(), void slotReset()) + Q_PRIVATE_SLOT(d_func(), void slotResetProperty()) }; class QtDoubleSpinBoxFactoryPrivate; @@ -374,6 +374,7 @@ private: const QMap &)) Q_PRIVATE_SLOT(d_func(), void slotSetValue(int)) Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *)) + Q_PRIVATE_SLOT(d_func(), void slotResetProperty()) }; class QtCursorEditorFactoryPrivate; From 3efd81023d0c052c8fe9fcad638845d1dba755ba Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Mon, 11 Jun 2012 00:41:02 +0300 Subject: [PATCH 83/89] Changed: #1302 Replaced VariantPropertyManager --HG-- branch : gsoc2011-worldeditorqt --- .../world_editor/property_editor_widget.cpp | 58 ++++++++++++++----- .../world_editor/property_editor_widget.h | 8 ++- 2 files changed, 51 insertions(+), 15 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.cpp index c3b9a3ba6..5acfe413f 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.cpp @@ -37,22 +37,32 @@ PropertyEditorWidget::PropertyEditorWidget(QWidget *parent) { m_ui.setupUi(this); - m_variantManager = new QtVariantPropertyManager(this); + m_stringManager = new QtStringPropertyManager(this); + m_boolManager = new QtBoolPropertyManager(this); m_enumManager = new QtEnumPropertyManager(this); m_stringArrayManager = new QtTextPropertyManager(this); - connect(m_variantManager, SIGNAL(valueChanged(QtProperty *, const QVariant &)), - this, SLOT(valueChanged(QtProperty *, const QVariant &))); - - QtVariantEditorFactory *variantFactory = new QtVariantEditorFactory(this); + QtLineEditFactory *lineEditFactory = new QtLineEditFactory(this); + QtCheckBoxFactory *boolFactory = new QtCheckBoxFactory(this); QtEnumEditorFactory *enumFactory = new QtEnumEditorFactory(this); QtTextEditorFactory *textFactory = new QtTextEditorFactory(this); - m_ui.treePropertyBrowser->setFactoryForManager(m_variantManager, variantFactory); + m_ui.treePropertyBrowser->setFactoryForManager(m_stringManager, lineEditFactory); + m_ui.treePropertyBrowser->setFactoryForManager(m_boolManager, boolFactory); m_ui.treePropertyBrowser->setFactoryForManager(m_enumManager, enumFactory); m_ui.treePropertyBrowser->setFactoryForManager(m_stringArrayManager, textFactory); m_groupManager = new QtGroupPropertyManager(this); + + connect(m_stringManager, SIGNAL(propertyChanged(QtProperty *)), this, SLOT(propertyChanged(QtProperty *))); + connect(m_boolManager, SIGNAL(propertyChanged(QtProperty *)), this, SLOT(propertyChanged(QtProperty *))); + connect(m_enumManager, SIGNAL(propertyChanged(QtProperty *)), this, SLOT(propertyChanged(QtProperty *))); + connect(m_stringArrayManager, SIGNAL(propertyChanged(QtProperty *)), this, SLOT(propertyChanged(QtProperty *))); + + connect(m_boolManager, SIGNAL(resetProperty(QtProperty *)), this, SLOT(resetProperty(QtProperty *))); + connect(m_stringManager, SIGNAL(resetProperty(QtProperty *)), this, SLOT(resetProperty(QtProperty *))); + connect(m_enumManager, SIGNAL(resetProperty(QtProperty *)), this, SLOT(resetProperty(QtProperty *))); + connect(m_stringArrayManager, SIGNAL(resetProperty(QtProperty *)), this, SLOT(resetProperty(QtProperty *))); } PropertyEditorWidget::~PropertyEditorWidget() @@ -71,6 +81,8 @@ void PropertyEditorWidget::updateSelection(Node *node) if ((node == 0) || (node->type() != Node::PrimitiveNodeType)) return; + blockSignalsOfProperties(true); + // The parameter list std::list parameterList; @@ -149,7 +161,6 @@ void PropertyEditorWidget::updateSelection(Node *node) else if (parameter.Type == NLLIGO::CPrimitiveClass::CParameter::ConstStringArray) prop = addConstStringArrayProperty(ligoProperty, parameter, primitive); else - // hmn? prop = addBoolProperty(ligoProperty, parameter, primitive); // Default value ? @@ -166,6 +177,18 @@ void PropertyEditorWidget::updateSelection(Node *node) ite++; } + + blockSignalsOfProperties(false); +} + +void PropertyEditorWidget::propertyChanged(QtProperty *property) +{ + nlinfo(QString("property %1 changed").arg(property->propertyName()).toStdString().c_str()); +} + +void PropertyEditorWidget::resetProperty(QtProperty *property) +{ + nlinfo(QString("property %1 reset").arg(property->propertyName()).toStdString().c_str()); } QtProperty *PropertyEditorWidget::addBoolProperty(const NLLIGO::IProperty *property, @@ -175,11 +198,11 @@ QtProperty *PropertyEditorWidget::addBoolProperty(const NLLIGO::IProperty *prope std::string value; std::string name = parameter.Name.c_str(); primitive->getPropertyByName(name.c_str(), value); - QtVariantProperty *prop = m_variantManager->addProperty(QVariant::Bool, name.c_str()); + QtProperty *prop = m_boolManager->addProperty(name.c_str()); // if (Default) { //DialogProperties->setDefaultValue (this, value); - prop->setValue(bool((value=="true")?1:0)); + m_boolManager->setValue(prop, bool((value=="true")?1:0)); } return prop; } @@ -242,7 +265,7 @@ QtProperty *PropertyEditorWidget::addConstStringProperty(const NLLIGO::IProperty if (listEnums.isEmpty()) { - listEnums << tr("WRN: Check leveldesign!"); + listEnums << QString(value.c_str()) + tr(" (WRN: Check leveldesign!)"); m_enumManager->setEnumNames(prop, listEnums); m_enumManager->setValue(prop, 0); prop->setEnabled(false); @@ -273,8 +296,8 @@ QtProperty *PropertyEditorWidget::addStringProperty(const NLLIGO::IProperty *pro std::string value; std::string name = parameter.Name.c_str(); primitive->getPropertyByName(name.c_str(), value); - QtVariantProperty *prop = m_variantManager->addProperty(QVariant::String, parameter.Name.c_str()); - prop->setValue(QString(value.c_str())); + QtProperty *prop = m_stringManager->addProperty(parameter.Name.c_str()); + m_stringManager->setValue(prop, QString(value.c_str())); return prop; } @@ -320,10 +343,17 @@ QtProperty *PropertyEditorWidget::addConstStringArrayProperty(const NLLIGO::IPro const NLLIGO::IPrimitive *primitive) { std::string name = parameter.Name.c_str(); - QtVariantProperty *prop = m_variantManager->addProperty(QVariant::String, parameter.Name.c_str()); - prop->setValue("TODO: ConstStringArray"); + QtProperty *prop = m_stringManager->addProperty(parameter.Name.c_str()); + m_stringManager->setValue(prop, "TODO: ConstStringArray"); prop->setEnabled(false); return prop; } +void PropertyEditorWidget::blockSignalsOfProperties(bool block) +{ + m_stringManager->blockSignals(block); + m_boolManager->blockSignals(block); + m_enumManager->blockSignals(block); + m_stringArrayManager->blockSignals(block); +} } /* namespace WorldEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.h index a4ccf9d5f..a9055b5af 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.h @@ -54,6 +54,9 @@ public Q_SLOTS: /// Update of selections void updateSelection(Node *node); + void propertyChanged(QtProperty *property); + void resetProperty(QtProperty *property); + private: QtProperty *addBoolProperty(const NLLIGO::IProperty *property, const NLLIGO::CPrimitiveClass::CParameter ¶meter, @@ -71,7 +74,10 @@ private: const NLLIGO::CPrimitiveClass::CParameter ¶meter, const NLLIGO::IPrimitive *primitive); - QtVariantPropertyManager *m_variantManager; + void blockSignalsOfProperties(bool block); + + QtBoolPropertyManager *m_boolManager; + QtStringPropertyManager *m_stringManager; QtEnumPropertyManager *m_enumManager; QtGroupPropertyManager *m_groupManager; QtTextPropertyManager *m_stringArrayManager; From 068b9bf7bb264715fdee23df174f6e470eb79203 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Sun, 2 Sep 2012 15:27:31 +0300 Subject: [PATCH 84/89] Changed: #1302 Polish code of property editor --HG-- branch : gsoc2011-worldeditorqt --- .../world_editor/property_editor_widget.cpp | 167 +++++++++++++----- .../world_editor/property_editor_widget.h | 2 + 2 files changed, 123 insertions(+), 46 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.cpp index 5acfe413f..d015adaf1 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.cpp @@ -173,6 +173,13 @@ void PropertyEditorWidget::updateSelection(Node *node) if (parameter.ReadOnly || (staticChildSelected && (parameter.Name == "name"))) prop->setEnabled(false); + // File ? + if (parameter.Filename && (parameter.FileExtension.empty() || parameter.Type != NLLIGO::CPrimitiveClass::CParameter::StringArray)) + { + // TODO: Create an edit box + // CHECK: only for ConstString + } + groupNode->addSubProperty(prop); ite++; @@ -211,10 +218,6 @@ QtProperty *PropertyEditorWidget::addConstStringProperty(const NLLIGO::IProperty const NLLIGO::CPrimitiveClass::CParameter ¶meter, const NLLIGO::IPrimitive *primitive) { - // TODO: get context value from dialog - std::string context("jungle"); - std::string defaultContext("default"); - std::string value; std::string name = parameter.Name.c_str(); @@ -224,44 +227,7 @@ QtProperty *PropertyEditorWidget::addConstStringProperty(const NLLIGO::IProperty // Create qt property QtProperty *prop = m_enumManager->addProperty(parameter.Name.c_str()); - std::vector listContext; - - if (context != defaultContext) - listContext.push_back(context); - listContext.push_back(defaultContext); - - QStringList listEnums; - - // Correct fill properties with *both* contexts if the current context is not default and is valid. - for (size_t j = 0; j < listContext.size(); j++) - { - std::map::const_iterator ite = parameter.ComboValues.find(listContext[j].c_str()); - - if (ite != parameter.ComboValues.end()) - { - std::vector pathList; - { - ite->second.appendFilePath(pathList); - - // TODO: what is it? - /*std::vector relativePrimPaths; - { - std::vector startPrimPath; - for (uint locIndex = 0; locIndex<_PropDlgLocators.size(); locIndex++) - startPrimPath.push_back(_PropDlgLocators[locIndex].Primitive); - - ite->second.getPrimitivesForPrimPath(relativePrimPaths, startPrimPath); - } - ite->second.appendPrimPath(pathList, relativePrimPaths);*/ - } - - if (parameter.SortEntries) - std::sort(pathList.begin(), pathList.end()); - - for (size_t i = 0; i < pathList.size(); ++i) - listEnums.append(pathList[i].c_str()); - } - } + QStringList listEnums = getComboValues(parameter); if (listEnums.isEmpty()) { @@ -272,6 +238,10 @@ QtProperty *PropertyEditorWidget::addConstStringProperty(const NLLIGO::IProperty } else { + // TODO: check this logic + if (parameter.DefaultValue.empty() || (parameter.DefaultValue[0].Name.empty())) + listEnums.prepend(""); + // Fill qt property m_enumManager->setEnumNames(prop, listEnums); @@ -311,7 +281,7 @@ QtProperty *PropertyEditorWidget::addStringArrayProperty(const NLLIGO::IProperty const NLLIGO::IProperty *ligoProperty; std::vector vectString; - if (primitive->getPropertyByName (parameter.Name.c_str (), ligoProperty)) + if (primitive->getPropertyByName(parameter.Name.c_str (), ligoProperty)) { const NLLIGO::CPropertyStringArray *const propStringArray = dynamic_cast (ligoProperty); if (propStringArray) @@ -335,6 +305,13 @@ QtProperty *PropertyEditorWidget::addStringArrayProperty(const NLLIGO::IProperty m_stringArrayManager->setValue(prop, "StringArray :("); } } + + // Create an "EDIT" button if the text is editable (FileExtension != "") + if (parameter.FileExtension != "") + { + // Create an edit box + // TODO: + } return prop; } @@ -342,13 +319,111 @@ QtProperty *PropertyEditorWidget::addConstStringArrayProperty(const NLLIGO::IPro const NLLIGO::CPrimitiveClass::CParameter ¶meter, const NLLIGO::IPrimitive *primitive) { + std::string value; std::string name = parameter.Name.c_str(); - QtProperty *prop = m_stringManager->addProperty(parameter.Name.c_str()); - m_stringManager->setValue(prop, "TODO: ConstStringArray"); - prop->setEnabled(false); + + // Get current value + primitive->getPropertyByName(name.c_str(), value); + + // Create qt property +// QtProperty *prop = m_enumManager->addProperty(parameter.Name.c_str()); + QtProperty *prop = m_stringArrayManager->addProperty(parameter.Name.c_str()); + + QStringList listEnums = getComboValues(parameter); + + if (listEnums.isEmpty()) + { +// listEnums << QString(value.c_str()) + tr(" (WRN: Check leveldesign!)"); +// m_enumManager->setEnumNames(prop, listEnums); +// m_enumManager->setValue(prop, 0); + prop->setEnabled(false); + } + else + { + // Fill qt property + m_enumManager->setEnumNames(prop, listEnums); + + // Find index of current value + //for (int i = 0; i < listEnums.size(); i++) + //{ + // if (value == listEnums[i].toStdString()) + // { + // m_enumManager->setValue(prop, i); + // break; + // } + //} + + const NLLIGO::IProperty *ligoProperty; + std::vector vectString; + + if (primitive->getPropertyByName (parameter.Name.c_str(), ligoProperty)) + { + const NLLIGO::CPropertyStringArray *const propStringArray = dynamic_cast (ligoProperty); + if (propStringArray) + { + const std::vector &vectString = propStringArray->StringArray; + if (!vectString.empty()) + { + std::string temp; + for (size_t i = 0; i < vectString.size(); i++) + { + temp += vectString[i]; + if (i != (vectString.size() - 1)) + temp += '\n'; + } + m_stringArrayManager->setValue(prop, temp.c_str()); + prop->setToolTip(temp.c_str()); + } + } + else + { + m_stringArrayManager->setValue(prop, "StringArray :("); + } + } + + m_enumManager->setValue(prop, 0); + } + return prop; } +QStringList PropertyEditorWidget::getComboValues(const NLLIGO::CPrimitiveClass::CParameter ¶meter) +{ + // TODO: get context value from dialog + std::string context("jungle"); + std::string defaultContext("default"); + + std::vector listContext; + + if (context != defaultContext) + listContext.push_back(context); + listContext.push_back(defaultContext); + + QStringList listEnums; + + // Correct fill properties with *both* contexts if the current context is not default and is valid. + for (size_t j = 0; j < listContext.size(); j++) + { + std::map::const_iterator ite = parameter.ComboValues.find(listContext[j].c_str()); + + if (ite != parameter.ComboValues.end()) + { + std::vector pathList; + + // Fill pathList + ite->second.appendFilePath(pathList); + + if (parameter.SortEntries) + std::sort(pathList.begin(), pathList.end()); + + for (size_t i = 0; i < pathList.size(); ++i) + listEnums.append(pathList[i].c_str()); + } + } + + return listEnums; +} + void PropertyEditorWidget::blockSignalsOfProperties(bool block) { m_stringManager->blockSignals(block); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.h index a9055b5af..85935cccd 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/property_editor_widget.h @@ -74,6 +74,8 @@ private: const NLLIGO::CPrimitiveClass::CParameter ¶meter, const NLLIGO::IPrimitive *primitive); + QStringList getComboValues(const NLLIGO::CPrimitiveClass::CParameter ¶meter); + void blockSignalsOfProperties(bool block); QtBoolPropertyManager *m_boolManager; From 602ca06998d7036846b4da631a92453a16804093 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Sun, 11 Nov 2012 13:33:43 +0300 Subject: [PATCH 85/89] Changed: Fixed crash land editor qt --HG-- branch : gsoc2011-worldeditorqt --- .../plugins/landscape_editor/builder_zone.cpp | 6 +- .../plugins/landscape_editor/builder_zone.h | 2 +- .../landscape_editor/builder_zone_region.cpp | 80 +++++++++++++++---- 3 files changed, 70 insertions(+), 18 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp index 8e3adf415..35e843481 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.cpp @@ -354,10 +354,14 @@ ZoneRegionObject *ZoneBuilder::zoneRegion(int id) const return result; } -void ZoneBuilder::ligoData(LigoData &data, const ZonePosition &zonePos) +bool ZoneBuilder::ligoData(LigoData &data, const ZonePosition &zonePos) { if (m_landscapeMap.contains(zonePos.region)) + { m_landscapeMap.value(zonePos.region).zoneRegionObject->ligoData(data, zonePos.x, zonePos.y); + return true; + } + return false; } void ZoneBuilder::setLigoData(LigoData &data, const ZonePosition &zonePos) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h index 41983641f..106b8ee58 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h @@ -111,7 +111,7 @@ public: ZoneRegionObject *currentZoneRegion() const; int countZoneRegion() const; ZoneRegionObject *zoneRegion(int id) const; - void ligoData(LigoData &data, const ZonePosition &zonePos); + bool ligoData(LigoData &data, const ZonePosition &zonePos); void setLigoData(LigoData &data, const ZonePosition &zonePos); /// @} diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.cpp index 33b48e04e..36c70d4c7 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_region.cpp @@ -247,7 +247,12 @@ void BuilderZoneRegion::add(sint32 x, sint32 y, uint8 rot, uint8 flip, NLLIGO::C void BuilderZoneRegion::invertCutEdge(sint32 x, sint32 y, uint8 cePos) { - const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->ligoZoneRegion(); + ZoneRegionObject *zoneRegionObj = m_zoneBuilder->zoneRegion(m_regionId); + + if (zoneRegionObj == 0) + return; + + const NLLIGO::CZoneRegion &zoneRegion = zoneRegionObj->ligoZoneRegion(); if ((x < zoneRegion.getMinX ()) || (x > zoneRegion.getMaxX ()) || (y < zoneRegion.getMinY ()) || (y > zoneRegion.getMaxY ())) return; @@ -354,12 +359,16 @@ void BuilderZoneRegion::invertCutEdge(sint32 x, sint32 y, uint8 cePos) void BuilderZoneRegion::cycleTransition(sint32 x, sint32 y) { - const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->ligoZoneRegion(); + ZoneRegionObject *zoneRegionObj = m_zoneBuilder->zoneRegion(m_regionId); + if (zoneRegionObj == 0) + return; + + const NLLIGO::CZoneRegion &zoneRegion = zoneRegionObj->ligoZoneRegion(); if ((x < zoneRegion.getMinX ()) || (x > zoneRegion.getMaxX ()) || (y < zoneRegion.getMinY ()) || (y > zoneRegion.getMaxY ())) return; - NLLIGO::CZoneBankElement *zoneBankElement = m_zoneBuilder->getZoneBank().getElementByZoneName (zoneRegion.getName (x, y)); + NLLIGO::CZoneBankElement *zoneBankElement = m_zoneBuilder->getZoneBank().getElementByZoneName(zoneRegion.getName (x, y)); if (zoneBankElement == NULL) return; if (zoneBankElement->getCategory("transname") == STRING_NO_CAT_TYPE) @@ -374,7 +383,11 @@ void BuilderZoneRegion::cycleTransition(sint32 x, sint32 y) bool BuilderZoneRegion::addNotPropagate (sint32 x, sint32 y, uint8 rot, uint8 flip, NLLIGO::CZoneBankElement *zoneBankElement) { - const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->ligoZoneRegion(); + ZoneRegionObject *zoneRegionObj = m_zoneBuilder->zoneRegion(m_regionId); + if (zoneRegionObj == 0) + return false; + + const NLLIGO::CZoneRegion &zoneRegion = zoneRegionObj->ligoZoneRegion(); sint32 sizeX = zoneBankElement->getSizeX(), sizeY = zoneBankElement->getSizeY(); sint32 i, j; NLLIGO::SPiece sMask, sPosX, sPosY; @@ -448,7 +461,11 @@ bool BuilderZoneRegion::addNotPropagate (sint32 x, sint32 y, uint8 rot, uint8 fl void BuilderZoneRegion::addForce (sint32 x, sint32 y, uint8 rot, uint8 flip, NLLIGO::CZoneBankElement *zoneBankElement) { - const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->ligoZoneRegion(); + ZoneRegionObject *zoneRegionObj = m_zoneBuilder->zoneRegion(m_regionId); + if (zoneRegionObj == 0) + return; + + const NLLIGO::CZoneRegion &zoneRegion = zoneRegionObj->ligoZoneRegion(); sint32 sizeX = zoneBankElement->getSizeX(), sizeY = zoneBankElement->getSizeY(); sint32 i, j; NLLIGO::SPiece sMask, sPosX, sPosY; @@ -612,7 +629,11 @@ uint8 TransToEdge[72][4] = void BuilderZoneRegion::addTransition (sint32 x, sint32 y, uint8 rot, uint8 flip, NLLIGO::CZoneBankElement *zoneBankElement) { - const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->ligoZoneRegion(); + ZoneRegionObject *zoneRegionObj = m_zoneBuilder->zoneRegion(m_regionId); + if (zoneRegionObj == 0) + return; + + const NLLIGO::CZoneRegion &zoneRegion = zoneRegionObj->ligoZoneRegion(); uint32 i; // Check that we write in an already defined place if ((x < zoneRegion.getMinX ()) || (x > zoneRegion.getMaxX ()) || @@ -783,7 +804,11 @@ void BuilderZoneRegion::addTransition (sint32 x, sint32 y, uint8 rot, uint8 flip void BuilderZoneRegion::addToUpdateAndCreate(BuilderZoneRegion *builderZoneRegion, sint32 sharePos, sint32 x, sint32 y, const std::string &newMat, ToUpdate *ptCreate, ToUpdate *ptUpdate) { - const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->ligoZoneRegion(); + ZoneRegionObject *zoneRegionObj = m_zoneBuilder->zoneRegion(m_regionId); + if (zoneRegionObj == 0) + return; + + const NLLIGO::CZoneRegion &zoneRegion = zoneRegionObj->ligoZoneRegion(); sint32 stride = (1 + zoneRegion.getMaxX() - zoneRegion.getMinX()); ZonePosition zonePos; @@ -806,7 +831,11 @@ void BuilderZoneRegion::addToUpdateAndCreate(BuilderZoneRegion *builderZoneRegio void BuilderZoneRegion::putTransitions (sint32 inX, sint32 inY, const NLLIGO::SPiece &mask, const std::string &matName, ToUpdate *ptUpdate) { - const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->ligoZoneRegion(); + ZoneRegionObject *zoneRegionObj = m_zoneBuilder->zoneRegion(m_regionId); + if (zoneRegionObj == 0) + return; + + const NLLIGO::CZoneRegion &zoneRegion = zoneRegionObj->ligoZoneRegion(); ToUpdate tCreate; // Transition to create sint32 i, j, k, l, m; @@ -956,7 +985,11 @@ void BuilderZoneRegion::putTransitions (sint32 inX, sint32 inY, const NLLIGO::SP // For all transition to update choose the cut edge for (m = 0; m < (sint32)tCreate.size(); ++m) { - const NLLIGO::CZoneRegion &zoneRegion2 = m_zoneBuilder->zoneRegion(tCreate.getBuilderZoneRegion(m)->getRegionId())->ligoZoneRegion(); + ZoneRegionObject *zoneRegionObj2 = m_zoneBuilder->zoneRegion(tCreate.getBuilderZoneRegion(m)->getRegionId()); + if (zoneRegionObj2 == 0) + continue; + + const NLLIGO::CZoneRegion &zoneRegion2 = zoneRegionObj2->ligoZoneRegion(); x = tCreate.getX(m); y = tCreate.getY(m); @@ -1125,14 +1158,16 @@ void BuilderZoneRegion::putTransitions (sint32 inX, sint32 inY, const NLLIGO::SP (y >= zoneRegion2.getMinY()) && (y <= zoneRegion2.getMaxY())) tCreate.getBuilderZoneRegion(m)->updateTrans(x, y); } + + // WARNING: TODO: check this for for (m = 0; m < (sint32)ptUpdate->size(); ++m) { - const NLLIGO::CZoneRegion &zoneRegion2 = m_zoneBuilder->zoneRegion(tCreate.getBuilderZoneRegion(m)->getRegionId())->ligoZoneRegion(); + const NLLIGO::CZoneRegion &zoneRegion2 = m_zoneBuilder->zoneRegion(ptUpdate->getBuilderZoneRegion(m)->getRegionId())->ligoZoneRegion(); x = ptUpdate->getX(m); y = ptUpdate->getY(m); if ((x >= zoneRegion2.getMinX()) && (x <= zoneRegion2.getMaxX()) && (y >= zoneRegion2.getMinY()) && (y <= zoneRegion2.getMaxY())) - tCreate.getBuilderZoneRegion(m)->updateTrans(x, y); + ptUpdate->getBuilderZoneRegion(m)->updateTrans(x, y); } // Cross material @@ -1370,7 +1405,7 @@ void BuilderZoneRegion::updateTrans (sint32 x, sint32 y, NLLIGO::CZoneBankElemen else { NLLIGO::CZoneBankElement *zoneBankElement2 = m_zoneBuilder->getZoneBank().getElementByZoneName(dataZoneTemp.zoneName); - if ((zoneBankElement != NULL) && (zoneBankElement2->getCategory("material") == dataZoneTemp.sharingMatNames[0])) + if ((zoneBankElement != NULL) && (zoneBankElement2 != NULL) && (zoneBankElement2->getCategory("material") == dataZoneTemp.sharingMatNames[0])) return; NLLIGO::CZoneBank &zoneBank = m_zoneBuilder->getZoneBank(); @@ -1572,7 +1607,11 @@ struct SNode void BuilderZoneRegion::tryPath(uint32 posA, uint32 posB, std::vector &path) { - const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->ligoZoneRegion(); + ZoneRegionObject *zoneRegionObj = m_zoneBuilder->zoneRegion(m_regionId); + if (zoneRegionObj == 0) + return; + + const NLLIGO::CZoneRegion &zoneRegion = zoneRegionObj->ligoZoneRegion(); // Build the adjascence matrix std::vector matAdj; @@ -1634,7 +1673,11 @@ void BuilderZoneRegion::tryPath(uint32 posA, uint32 posB, std::vector &p void BuilderZoneRegion::del(sint32 x, sint32 y, bool transition, ToUpdate *pUpdate) { - const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->ligoZoneRegion(); + ZoneRegionObject *zoneRegionObj = m_zoneBuilder->zoneRegion(m_regionId); + if (zoneRegionObj == 0) + return; + + const NLLIGO::CZoneRegion &zoneRegion = zoneRegionObj->ligoZoneRegion(); if (!m_zoneBuilder->getZoneMask(x, y)) return; @@ -1768,7 +1811,11 @@ uint32 BuilderZoneRegion::countZones () void BuilderZoneRegion::set(sint32 x, sint32 y, sint32 posX, sint32 posY, const std::string &zoneName, bool transition) { - const NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->zoneRegion(m_regionId)->ligoZoneRegion(); + ZoneRegionObject *zoneRegionObj = m_zoneBuilder->zoneRegion(m_regionId); + if (zoneRegionObj == 0) + return; + + const NLLIGO::CZoneRegion &zoneRegion = zoneRegionObj->ligoZoneRegion(); // Do we need to resize ? if ((x < zoneRegion.getMinX()) || (x > zoneRegion.getMaxX()) || @@ -1782,7 +1829,8 @@ void BuilderZoneRegion::set(sint32 x, sint32 y, sint32 posX, sint32 posY, ZonePosition zonePosTemp(x, y, m_regionId); LigoData dataZoneTemp; - m_zoneBuilder->ligoData(dataZoneTemp, zonePosTemp); + if (!m_zoneBuilder->ligoData(dataZoneTemp, zonePosTemp)) + return; LigoData dataZoneTempOriginal = dataZoneTemp; dataZoneTemp.zoneName = zoneName; From d62b9db23cfd2807a2b18957d7a080adf46908aa Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Sat, 15 Dec 2012 00:41:29 +0300 Subject: [PATCH 86/89] Change: Fixed incorrect behavior scroll of 2d view in landscape editor qt --HG-- branch : gsoc2011-worldeditorqt --- .../landscape_editor/landscape_view.cpp | 44 ++++++------------- 1 file changed, 14 insertions(+), 30 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp index 87a459511..7a612208a 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp @@ -70,41 +70,24 @@ void LandscapeView::setVisibleText(bool visible) void LandscapeView::wheelEvent(QWheelEvent *event) { - //nlinfo(QString("%1").arg(transform().m11()).toStdString().c_str()); + //How fast we zoom + float numSteps = (( event->delta() / 8 ) / 15) * 1.2; - //Get the position of the mouse before scaling, in scene coords - QPointF pointBeforeScale(mapToScene(event->pos())); + QMatrix mat = matrix(); + QPointF mousePosition = event->pos(); - //Get the original screen centerpoint - QPointF screenCenter = getCenter(); //CurrentCenterPoint; //(visRect.center()); + mat.translate((width() / 2) - mousePosition.x(), (height() / 2) - mousePosition.y()); - //Scale the view ie. do the zoom - double scaleFactor = 1.15; //How fast we zoom - if(event->delta() > 0) - { - if (transform().m11() > m_minView ) - return; - //Zoom in - scale(scaleFactor, scaleFactor); - } + if ( numSteps > 0 ) + mat.scale(numSteps, numSteps); else - { - if (transform().m11() < m_maxView ) - return; - - //Zooming out - scale(1.0 / scaleFactor, 1.0 / scaleFactor); - } - - //Get the position after scaling, in scene coords - QPointF pointAfterScale(mapToScene(event->pos())); - - //Get the offset of how the screen moved - QPointF offset = pointBeforeScale - pointAfterScale; + mat.scale(-1 / numSteps, -1 / numSteps); + mat.translate(mousePosition.x() - (width() / 2), mousePosition.y() - (height() / 2)); + //Adjust to the new center for correct zooming - QPointF newCenter = screenCenter + offset; - setCenter(newCenter); + setMatrix(mat); + event->accept(); } void LandscapeView::mousePressEvent(QMouseEvent *event) @@ -202,7 +185,8 @@ void LandscapeView::setCenter(const QPointF ¢erPoint) QPointF LandscapeView::getCenter() const { - return m_currentCenterPoint; + //return m_currentCenterPoint; + return mapToScene(viewport()->rect().center()); } void LandscapeView::drawForeground(QPainter *painter, const QRectF &rect) From d86f150caa025e08cccccbada9b8a8bded616da4 Mon Sep 17 00:00:00 2001 From: sfb Date: Mon, 28 Oct 2013 11:24:02 -0500 Subject: [PATCH 87/89] Bad merge resolution, fixed the build files that merged poorly. --HG-- branch : gsoc2011-worldeditorqt --- .../src/plugins/landscape_editor/CMakeLists.txt | 2 +- .../object_viewer_qt/src/plugins/world_editor/CMakeLists.txt | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt index efc90a3b8..222a9c182 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt @@ -41,7 +41,7 @@ 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} diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/CMakeLists.txt index 694467f42..32f3950d9 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/CMakeLists.txt +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/CMakeLists.txt @@ -65,4 +65,6 @@ 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) +INSTALL(TARGETS ovqt_plugin_world_editor LIBRARY DESTINATION ${OVQT_PLUGIN_DIR} RUNTIME DESTINATION ${NL_BIN_PREFIX} ARCHIVE DESTINATION ${OVQT_PLUGIN_DIR} COMPONENT tools3d) +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/ovqt_plugin_world_editor.xml DESTINATION ${OVQT_PLUGIN_SPECS_DIR} COMPONENT tools3d) + From df7110d2d64e83c1dc95e180c74ed4d9284a7517 Mon Sep 17 00:00:00 2001 From: sfb Date: Mon, 28 Oct 2013 11:24:31 -0500 Subject: [PATCH 88/89] Bad merge resolution, fixed a couple source files which merged poorly. --HG-- branch : gsoc2011-worldeditorqt --- code/nel/src/ligo/zone_bank.cpp | 713 +----------------- .../landscape_editor_plugin.cpp | 27 - 2 files changed, 6 insertions(+), 734 deletions(-) diff --git a/code/nel/src/ligo/zone_bank.cpp b/code/nel/src/ligo/zone_bank.cpp index 4dee45e7e..ff24821af 100644 --- a/code/nel/src/ligo/zone_bank.cpp +++ b/code/nel/src/ligo/zone_bank.cpp @@ -1,704 +1,3 @@ -<<<<<<< local -// NeL - MMORPG Framework -// 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 . - - -#include "stdligo.h" - -#include "nel/ligo/zone_bank.h" - -#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 -#endif // NL_OS_WINDOWS - -using namespace std; -using namespace NLMISC; - - -namespace NLLIGO -{ - -// *************************************************************************** -// CZoneBankElement -// *************************************************************************** - -string CZoneBankElement::_NoCatTypeFound = STRING_NO_CAT_TYPE; - -// --------------------------------------------------------------------------- -CZoneBankElement::CZoneBankElement() -{ - _SizeX = _SizeY = 0; -} - -// --------------------------------------------------------------------------- -void CZoneBankElement::addCategory (const std::string &CatType, const std::string &CatValue) -{ - _CategoriesMap.insert(pair(CatType, CatValue)); -} - -// --------------------------------------------------------------------------- -const string& CZoneBankElement::getName () -{ - return getCategory ("zone"); -} - -// --------------------------------------------------------------------------- -const string& CZoneBankElement::getSize () -{ - return getCategory ("size"); -} - -// --------------------------------------------------------------------------- -const string& CZoneBankElement::getCategory (const string &CatType) -{ - map::iterator it = _CategoriesMap.find (CatType); - if (it == _CategoriesMap.end()) - return _NoCatTypeFound; - else - return it->second; -} - -// --------------------------------------------------------------------------- -void CZoneBankElement::convertSize() -{ - const string &sizeString = getSize(); - string sTmp; - uint32 i; - - for (i = 0; i < sizeString.size(); ++i) - { - if (sizeString[i] == 'x') - break; - else - sTmp += sizeString[i]; - } - fromString(sTmp, _SizeX); - - ++i; sTmp = ""; - for (; i < sizeString.size(); ++i) - { - sTmp += sizeString[i]; - } - fromString(sTmp, _SizeY); -} - -// --------------------------------------------------------------------------- -void CZoneBankElement::serial (NLMISC::IStream &f) -{ - f.xmlPush ("LIGOZONE"); - - sint version = 1; - f.serialVersion (version); - string check = "LIGOZONE"; - f.serialCheck (check); - - f.xmlPush ("CATEGORIES"); - f.serialCont (_CategoriesMap); - f.xmlPop (); - - f.xmlPush ("MASK"); - f.serialCont (_Mask); - f.xmlPop (); - - f.xmlPop (); - - convertSize(); -} - - -// --------------------------------------------------------------------------- -void CZoneBankElement::setMask (const std::vector &mask, uint8 sizeX, uint8 sizeY) -{ - _SizeX = sizeX; - _SizeY = sizeY; - _Mask = mask; -} - -// *************************************************************************** -// CZoneBank -// *************************************************************************** - -// --------------------------------------------------------------------------- -void CZoneBank::debugSaveInit (CZoneBankElement &zbeTmp, const string &fileName) -{ - try - { - COFile fileOut; - fileOut.open (fileName); - COXml output; - output.init (&fileOut); - zbeTmp.serial (output); - } - catch (const Exception& /*e*/) - { - } - -} - -// --------------------------------------------------------------------------- -void CZoneBank::debugInit(const std::string &sPath) // \ todo trap remove this -{ - CZoneBankElement zbeTmp; - zbeTmp.addCategory ("zone", "Zone001"); - zbeTmp.addCategory ("size", "1x1"); - zbeTmp.addCategory ("material", "titFleur"); - zbeTmp._Mask.push_back (true); - _ElementsMap.insert (pair(zbeTmp.getName(), zbeTmp)); - debugSaveInit (zbeTmp, sPath + "Zone001.ligozone"); - zbeTmp._CategoriesMap.clear (); - zbeTmp._Mask.clear (); - - - zbeTmp.addCategory ("zone", "Zone002"); - zbeTmp.addCategory ("size", "1x1"); - zbeTmp.addCategory ("material", "titFleur"); - zbeTmp._Mask.push_back (true); - _ElementsMap.insert (pair(zbeTmp.getName(), zbeTmp)); - debugSaveInit (zbeTmp, sPath + "Zone002.ligozone"); - zbeTmp._CategoriesMap.clear (); - zbeTmp._Mask.clear (); - - zbeTmp.addCategory ("zone", "Zone003"); - zbeTmp.addCategory ("size", "2x2"); - zbeTmp.addCategory ("material", "titFleur"); - zbeTmp._Mask.push_back (true); - zbeTmp._Mask.push_back (true); - zbeTmp._Mask.push_back (false); - zbeTmp._Mask.push_back (true); - _ElementsMap.insert (pair(zbeTmp.getName(), zbeTmp)); - debugSaveInit (zbeTmp, sPath + "Zone003.ligozone"); - zbeTmp._CategoriesMap.clear (); - zbeTmp._Mask.clear (); - - zbeTmp.addCategory ("zone", "Zone004"); - zbeTmp.addCategory ("size", "2x2"); - zbeTmp.addCategory ("material", "grozFleur"); - zbeTmp._Mask.push_back (false); - zbeTmp._Mask.push_back (true); - zbeTmp._Mask.push_back (true); - zbeTmp._Mask.push_back (true); - _ElementsMap.insert (pair(zbeTmp.getName(), zbeTmp)); - debugSaveInit (zbeTmp, sPath + "Zone004.ligozone"); - zbeTmp._CategoriesMap.clear (); - zbeTmp._Mask.clear (); - - zbeTmp.addCategory ("zone", "Zone005"); - zbeTmp.addCategory ("size", "1x1"); - zbeTmp.addCategory ("material", "grozFleur"); - zbeTmp._Mask.push_back (true); - _ElementsMap.insert (pair(zbeTmp.getName(), zbeTmp)); - debugSaveInit (zbeTmp, sPath + "Zone005.ligozone"); - zbeTmp._CategoriesMap.clear (); - zbeTmp._Mask.clear (); - - zbeTmp.addCategory ("zone", "Zone006"); - zbeTmp.addCategory ("size", "4x2"); - zbeTmp.addCategory ("material", "grozFleur"); - zbeTmp._Mask.push_back (true); - zbeTmp._Mask.push_back (true); - zbeTmp._Mask.push_back (false); - zbeTmp._Mask.push_back (false); - zbeTmp._Mask.push_back (false); - zbeTmp._Mask.push_back (true); - zbeTmp._Mask.push_back (true); - zbeTmp._Mask.push_back (false); - _ElementsMap.insert (pair(zbeTmp.getName(), zbeTmp)); - debugSaveInit (zbeTmp, sPath + "Zone006.ligozone"); - zbeTmp._CategoriesMap.clear (); - zbeTmp._Mask.clear (); - _ElementsMap.clear (); - - zbeTmp.addCategory ("zone", "Zone007"); - zbeTmp.addCategory ("size", "1x1"); - zbeTmp.addCategory ("material", "grozFleur"); - zbeTmp._Mask.push_back (true); - _ElementsMap.insert (pair(zbeTmp.getName(), zbeTmp)); - debugSaveInit (zbeTmp, sPath + "Zone007.ligozone"); - zbeTmp._CategoriesMap.clear (); - zbeTmp._Mask.clear (); - _ElementsMap.clear (); - - zbeTmp.addCategory ("zone", "Zone008"); - zbeTmp.addCategory ("size", "2x2"); - zbeTmp.addCategory ("material", "prairie"); - zbeTmp._Mask.push_back (true); - zbeTmp._Mask.push_back (true); - zbeTmp._Mask.push_back (true); - zbeTmp._Mask.push_back (true); - _ElementsMap.insert (pair(zbeTmp.getName(), zbeTmp)); - debugSaveInit (zbeTmp, sPath + "Zone008.ligozone"); - zbeTmp._CategoriesMap.clear (); - zbeTmp._Mask.clear (); - _ElementsMap.clear (); - - zbeTmp.addCategory ("zone", "Zone009"); - zbeTmp.addCategory ("size", "2x2"); - zbeTmp.addCategory ("material", "prairie"); - zbeTmp._Mask.push_back (true); - zbeTmp._Mask.push_back (true); - zbeTmp._Mask.push_back (true); - zbeTmp._Mask.push_back (true); - _ElementsMap.insert (pair(zbeTmp.getName(), zbeTmp)); - debugSaveInit (zbeTmp, sPath + "Zone009.ligozone"); - zbeTmp._CategoriesMap.clear (); - zbeTmp._Mask.clear (); - _ElementsMap.clear (); - - zbeTmp.addCategory ("zone", "Zone010"); - zbeTmp.addCategory ("size", "1x1"); - zbeTmp.addCategory ("material", "prairie"); - zbeTmp._Mask.push_back (true); - _ElementsMap.insert (pair(zbeTmp.getName(), zbeTmp)); - debugSaveInit (zbeTmp, sPath + "Zone010.ligozone"); - zbeTmp._CategoriesMap.clear (); - zbeTmp._Mask.clear (); - _ElementsMap.clear (); - - zbeTmp.addCategory ("zone", "WT0"); - zbeTmp.addCategory ("size", "1x1"); - zbeTmp.addCategory ("transname", "grozFleur-prairie"); - zbeTmp.addCategory ("transtype", "Flat"); - zbeTmp.addCategory ("transnum", "0"); - zbeTmp._Mask.push_back (true); - _ElementsMap.insert (pair(zbeTmp.getName(), zbeTmp)); - debugSaveInit (zbeTmp, sPath + "WT0.ligozone"); - zbeTmp._CategoriesMap.clear (); - zbeTmp._Mask.clear (); - _ElementsMap.clear (); - - zbeTmp.addCategory ("zone", "WT1"); - zbeTmp.addCategory ("size", "1x1"); - zbeTmp.addCategory ("transname", "grozFleur-prairie"); - zbeTmp.addCategory ("transtype", "Flat"); - zbeTmp.addCategory ("transnum", "1"); - zbeTmp._Mask.push_back (true); - _ElementsMap.insert (pair(zbeTmp.getName(), zbeTmp)); - debugSaveInit (zbeTmp, sPath + "WT1.ligozone"); - zbeTmp._CategoriesMap.clear (); - zbeTmp._Mask.clear (); - _ElementsMap.clear (); - - zbeTmp.addCategory ("zone", "WT2"); - zbeTmp.addCategory ("size", "1x1"); - zbeTmp.addCategory ("transname", "grozFleur-prairie"); - zbeTmp.addCategory ("transtype", "Flat"); - zbeTmp.addCategory ("transnum", "2"); - zbeTmp._Mask.push_back (true); - _ElementsMap.insert (pair(zbeTmp.getName(), zbeTmp)); - debugSaveInit (zbeTmp, sPath + "WT2.ligozone"); - zbeTmp._CategoriesMap.clear (); - zbeTmp._Mask.clear (); - _ElementsMap.clear (); - - zbeTmp.addCategory ("zone", "WT3"); - zbeTmp.addCategory ("size", "1x1"); - zbeTmp.addCategory ("transname", "grozFleur-prairie"); - zbeTmp.addCategory ("transtype", "CornerA"); - zbeTmp.addCategory ("transnum", "3"); - zbeTmp._Mask.push_back (true); - _ElementsMap.insert (pair(zbeTmp.getName(), zbeTmp)); - debugSaveInit (zbeTmp, sPath + "WT3.ligozone"); - zbeTmp._CategoriesMap.clear (); - zbeTmp._Mask.clear (); - _ElementsMap.clear (); - - zbeTmp.addCategory ("zone", "WT4"); - zbeTmp.addCategory ("size", "1x1"); - zbeTmp.addCategory ("transname", "grozFleur-prairie"); - zbeTmp.addCategory ("transtype", "CornerA"); - zbeTmp.addCategory ("transnum", "4"); - zbeTmp._Mask.push_back (true); - _ElementsMap.insert (pair(zbeTmp.getName(), zbeTmp)); - debugSaveInit (zbeTmp, sPath + "WT4.ligozone"); - zbeTmp._CategoriesMap.clear (); - zbeTmp._Mask.clear (); - _ElementsMap.clear (); - - zbeTmp.addCategory ("zone", "WT5"); - zbeTmp.addCategory ("size", "1x1"); - zbeTmp.addCategory ("transname", "grozFleur-prairie"); - zbeTmp.addCategory ("transtype", "CornerA"); - zbeTmp.addCategory ("transnum", "5"); - zbeTmp._Mask.push_back (true); - _ElementsMap.insert (pair(zbeTmp.getName(), zbeTmp)); - debugSaveInit (zbeTmp, sPath + "WT5.ligozone"); - zbeTmp._CategoriesMap.clear (); - zbeTmp._Mask.clear (); - _ElementsMap.clear (); - - zbeTmp.addCategory ("zone", "WT6"); - zbeTmp.addCategory ("size", "1x1"); - zbeTmp.addCategory ("transname", "grozFleur-prairie"); - zbeTmp.addCategory ("transtype", "CornerB"); - zbeTmp.addCategory ("transnum", "6"); - zbeTmp._Mask.push_back (true); - _ElementsMap.insert (pair(zbeTmp.getName(), zbeTmp)); - debugSaveInit (zbeTmp, sPath + "WT6.ligozone"); - zbeTmp._CategoriesMap.clear (); - zbeTmp._Mask.clear (); - _ElementsMap.clear (); - - zbeTmp.addCategory ("zone", "WT7"); - zbeTmp.addCategory ("size", "1x1"); - zbeTmp.addCategory ("transname", "grozFleur-prairie"); - zbeTmp.addCategory ("transtype", "CornerB"); - zbeTmp.addCategory ("transnum", "7"); - zbeTmp._Mask.push_back (true); - _ElementsMap.insert (pair(zbeTmp.getName(), zbeTmp)); - debugSaveInit (zbeTmp, sPath + "WT7.ligozone"); - zbeTmp._CategoriesMap.clear (); - zbeTmp._Mask.clear (); - _ElementsMap.clear (); - - zbeTmp.addCategory ("zone", "WT8"); - zbeTmp.addCategory ("size", "1x1"); - zbeTmp.addCategory ("transname", "grozFleur-prairie"); - zbeTmp.addCategory ("transtype", "CornerB"); - zbeTmp.addCategory ("transnum", "8"); - zbeTmp._Mask.push_back (true); - _ElementsMap.insert (pair(zbeTmp.getName(), zbeTmp)); - debugSaveInit (zbeTmp, sPath + "WT8.ligozone"); - zbeTmp._CategoriesMap.clear (); - zbeTmp._Mask.clear (); - _ElementsMap.clear (); - - zbeTmp.addCategory ("zone", "ZT0"); - zbeTmp.addCategory ("size", "1x1"); - zbeTmp.addCategory ("transname", "titFleur-grozFleur"); - zbeTmp.addCategory ("transtype", "Flat"); - zbeTmp.addCategory ("transnum", "0"); - zbeTmp._Mask.push_back (true); - _ElementsMap.insert (pair(zbeTmp.getName(), zbeTmp)); - debugSaveInit (zbeTmp, sPath + "ZT0.ligozone"); - zbeTmp._CategoriesMap.clear (); - zbeTmp._Mask.clear (); - _ElementsMap.clear (); - - zbeTmp.addCategory ("zone", "ZT1"); - zbeTmp.addCategory ("size", "1x1"); - zbeTmp.addCategory ("transname", "titFleur-grozFleur"); - zbeTmp.addCategory ("transtype", "Flat"); - zbeTmp.addCategory ("transnum", "1"); - zbeTmp._Mask.push_back (true); - _ElementsMap.insert (pair(zbeTmp.getName(), zbeTmp)); - debugSaveInit (zbeTmp, sPath + "ZT1.ligozone"); - zbeTmp._CategoriesMap.clear (); - zbeTmp._Mask.clear (); - _ElementsMap.clear (); - - zbeTmp.addCategory ("zone", "ZT2"); - zbeTmp.addCategory ("size", "1x1"); - zbeTmp.addCategory ("transname", "titFleur-grozFleur"); - zbeTmp.addCategory ("transtype", "Flat"); - zbeTmp.addCategory ("transnum", "2"); - zbeTmp._Mask.push_back (true); - _ElementsMap.insert (pair(zbeTmp.getName(), zbeTmp)); - debugSaveInit (zbeTmp, sPath + "ZT2.ligozone"); - zbeTmp._CategoriesMap.clear (); - zbeTmp._Mask.clear (); - _ElementsMap.clear (); - - zbeTmp.addCategory ("zone", "ZT3"); - zbeTmp.addCategory ("size", "1x1"); - zbeTmp.addCategory ("transname", "titFleur-grozFleur"); - zbeTmp.addCategory ("transtype", "CornerA"); - zbeTmp.addCategory ("transnum", "3"); - zbeTmp._Mask.push_back (true); - _ElementsMap.insert (pair(zbeTmp.getName(), zbeTmp)); - debugSaveInit (zbeTmp, sPath + "ZT3.ligozone"); - zbeTmp._CategoriesMap.clear (); - zbeTmp._Mask.clear (); - _ElementsMap.clear (); - - zbeTmp.addCategory ("zone", "ZT4"); - zbeTmp.addCategory ("size", "1x1"); - zbeTmp.addCategory ("transname", "titFleur-grozFleur"); - zbeTmp.addCategory ("transtype", "CornerA"); - zbeTmp.addCategory ("transnum", "4"); - zbeTmp._Mask.push_back (true); - _ElementsMap.insert (pair(zbeTmp.getName(), zbeTmp)); - debugSaveInit (zbeTmp, sPath + "ZT4.ligozone"); - zbeTmp._CategoriesMap.clear (); - zbeTmp._Mask.clear (); - _ElementsMap.clear (); - - zbeTmp.addCategory ("zone", "ZT5"); - zbeTmp.addCategory ("size", "1x1"); - zbeTmp.addCategory ("transname", "titFleur-grozFleur"); - zbeTmp.addCategory ("transtype", "CornerA"); - zbeTmp.addCategory ("transnum", "5"); - zbeTmp._Mask.push_back (true); - _ElementsMap.insert (pair(zbeTmp.getName(), zbeTmp)); - debugSaveInit (zbeTmp, sPath + "ZT5.ligozone"); - zbeTmp._CategoriesMap.clear (); - zbeTmp._Mask.clear (); - _ElementsMap.clear (); - - zbeTmp.addCategory ("zone", "ZT6"); - zbeTmp.addCategory ("size", "1x1"); - zbeTmp.addCategory ("transname", "titFleur-grozFleur"); - zbeTmp.addCategory ("transtype", "CornerB"); - zbeTmp.addCategory ("transnum", "6"); - zbeTmp._Mask.push_back (true); - _ElementsMap.insert (pair(zbeTmp.getName(), zbeTmp)); - debugSaveInit (zbeTmp, sPath + "ZT6.ligozone"); - zbeTmp._CategoriesMap.clear (); - zbeTmp._Mask.clear (); - _ElementsMap.clear (); - - zbeTmp.addCategory ("zone", "ZT7"); - zbeTmp.addCategory ("size", "1x1"); - zbeTmp.addCategory ("transname", "titFleur-grozFleur"); - zbeTmp.addCategory ("transtype", "CornerB"); - zbeTmp.addCategory ("transnum", "7"); - zbeTmp._Mask.push_back (true); - _ElementsMap.insert (pair(zbeTmp.getName(), zbeTmp)); - debugSaveInit (zbeTmp, sPath + "ZT7.ligozone"); - zbeTmp._CategoriesMap.clear (); - zbeTmp._Mask.clear (); - _ElementsMap.clear (); - - zbeTmp.addCategory ("zone", "ZT8"); - zbeTmp.addCategory ("size", "1x1"); - zbeTmp.addCategory ("transname", "titFleur-grozFleur"); - zbeTmp.addCategory ("transtype", "CornerB"); - zbeTmp.addCategory ("transnum", "8"); - zbeTmp._Mask.push_back (true); - _ElementsMap.insert (pair(zbeTmp.getName(), zbeTmp)); - debugSaveInit (zbeTmp, sPath + "ZT8.ligozone"); - zbeTmp._CategoriesMap.clear (); - zbeTmp._Mask.clear (); - _ElementsMap.clear (); - -} - -// --------------------------------------------------------------------------- -void CZoneBank::reset () -{ - _ElementsMap.clear (); - _Selection.clear (); -} - -#ifdef NL_OS_WINDOWS -// --------------------------------------------------------------------------- -bool CZoneBank::initFromPath(const std::string &sPathName, std::string &error) -{ - char sDirBackup[512]; - GetCurrentDirectory (512, sDirBackup); - SetCurrentDirectory (sPathName.c_str()); - WIN32_FIND_DATA findData; - HANDLE hFind; - hFind = FindFirstFile ("*.ligozone", &findData); - - while (hFind != INVALID_HANDLE_VALUE) - { - // If the name of the file is not . or .. then its a valid entry in the DataBase - if (!((strcmp (findData.cFileName, ".") == 0) || (strcmp (findData.cFileName, "..") == 0))) - { - if (!addElement (findData.cFileName, error)) - return false; - } - if (FindNextFile (hFind, &findData) == 0) - break; - } - SetCurrentDirectory (sDirBackup); - return true; -} -#endif // NL_OS_WINDOWS - -// --------------------------------------------------------------------------- -bool CZoneBank::addElement (const std::string &elementName, std::string &error) -{ - try - { - CZoneBankElement zbeTmp; - CIFile fileIn; - if (fileIn.open (elementName)) - { - CIXml input; - input.init (fileIn); - zbeTmp.serial (input); - _ElementsMap.insert (pair(zbeTmp.getName(),zbeTmp)); - return true; - } - else - { - error = "Can't open file " + elementName; - } - } - catch (const Exception& e) - { - error = "Error while loading ligozone "+elementName+" : "+e.what(); - } - return false; -} - -// --------------------------------------------------------------------------- -void CZoneBank::getCategoriesType (std::vector &CategoriesType) -{ - map::iterator itElt = _ElementsMap.begin(); - - while (itElt != _ElementsMap.end()) - { - CZoneBankElement &rZBE = itElt->second; - - map::iterator it = rZBE._CategoriesMap.begin(); - - while (it != rZBE._CategoriesMap.end()) - { - bool bFound = false; - for (uint32 k = 0; k < CategoriesType.size(); ++k) - if (it->first == CategoriesType[k]) - { - bFound = true; - break; - } - if (!bFound) - CategoriesType.push_back (it->first); - - ++it; - } - ++itElt; - } -} - -// --------------------------------------------------------------------------- -void CZoneBank::getCategoryValues (const std::string &CategoryType, std::vector &CategoryValues) -{ - map::iterator itElt = _ElementsMap.begin(); - - while (itElt != _ElementsMap.end()) - { - CZoneBankElement &rZBE = itElt->second; - - map::iterator it = rZBE._CategoriesMap.find (CategoryType); - - if (it != rZBE._CategoriesMap.end()) - { - bool bFound = false; - for (uint32 k = 0; k < CategoryValues.size(); ++k ) - if (it->second == CategoryValues[k]) - { - bFound = true; - break; - } - if (!bFound) - CategoryValues.push_back (it->second); - } - ++itElt; - } -} - -// --------------------------------------------------------------------------- -CZoneBankElement *CZoneBank::getElementByZoneName (const std::string &ZoneName) -{ - map::iterator it = _ElementsMap.find (ZoneName); - if (it != _ElementsMap.end()) - { - return &(it->second); - } - return NULL; -} - -// --------------------------------------------------------------------------- -void CZoneBank::resetSelection () -{ - _Selection.clear (); -} - -// --------------------------------------------------------------------------- -void CZoneBank::addOrSwitch (const std::string &CategoryType, const std::string &CategoryValue) -{ - map::iterator itElt = _ElementsMap.begin(); - - while (itElt != _ElementsMap.end()) - { - CZoneBankElement &rZBE = itElt->second; - - map::iterator it = rZBE._CategoriesMap.find (CategoryType); - - if (it != rZBE._CategoriesMap.end()) - { - if (it->second == CategoryValue) - { - // Check if the element is not already present in the selection - bool bFound = false; - for (uint32 k = 0; k < _Selection.size(); ++k ) - if (&rZBE == _Selection[k]) - { - bFound = true; - break; - } - if (!bFound) - _Selection.push_back (&rZBE); - } - } - ++itElt; - } -} - -// --------------------------------------------------------------------------- -void CZoneBank::addAndSwitch (const std::string &CategoryType, const std::string &CategoryValue) -{ - uint32 i, j; - // And the selection with some constraints - // All elements of the selection must have a catType and catValue equal to those given in parameters - for (i = 0; i < _Selection.size(); ++i) - { - CZoneBankElement *pZBE = _Selection[i]; - bool bFound = false; - - map::iterator it = pZBE->_CategoriesMap.find (CategoryType); - if (it != pZBE->_CategoriesMap.end()) - { - if (it->second == CategoryValue) - bFound = true; - } - if (!bFound) - { - _Selection[i] = NULL; // Mark this item to be removed - } - } - // Remove all unused items - for (i = 0, j = 0; i < _Selection.size(); ++i) - { - if (_Selection[i] != NULL) - { - _Selection[j] = _Selection[i]; - ++j; - } - } - _Selection.resize (j); -} - -// --------------------------------------------------------------------------- -void CZoneBank::getSelection (std::vector &SelectedElements) -{ - SelectedElements = _Selection; -} - -// *************************************************************************** - -} // namespace NLLIGO======= // NeL - MMORPG Framework // Copyright (C) 2010 Winch Gate Property Limited // @@ -720,14 +19,15 @@ void CZoneBank::getSelection (std::vector &SelectedElements) #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 +#endif // NL_OS_WINDOWS using namespace std; using namespace NLMISC; @@ -1197,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); @@ -1221,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) @@ -1396,6 +698,3 @@ void CZoneBank::getSelection (std::vector &SelectedElements) // *************************************************************************** } // namespace NLLIGO - -#endif // NL_OS_WINDOWS ->>>>>>> other diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_plugin.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_plugin.cpp index 6ac2d58a3..17556d03f 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_plugin.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_plugin.cpp @@ -68,33 +68,6 @@ void LandscapeEditorPlugin::setNelContext(NLMISC::INelContext *nelContext) m_libContext = new NLMISC::CLibraryContext(*nelContext); } -QString LandscapeEditorPlugin::name() const -{ - return tr("LandscapeEditor"); -} - -QString LandscapeEditorPlugin::version() const -{ - return "0.0.1"; -} - -QString LandscapeEditorPlugin::vendor() const -{ - return "GSoC2011_dnk-88"; -} - -QString LandscapeEditorPlugin::description() const -{ - return "Landscape editor ovqt plugin."; -} - -QStringList LandscapeEditorPlugin::dependencies() const -{ - QStringList list; - list.append(Core::Constants::OVQT_CORE_PLUGIN); - return list; -} - void LandscapeEditorPlugin::addAutoReleasedObject(QObject *obj) { m_plugMan->addObject(obj); From 59abfb8a1d0cfa9080581c840a8d592ec7302d93 Mon Sep 17 00:00:00 2001 From: sfb Date: Mon, 28 Oct 2013 12:58:08 -0500 Subject: [PATCH 89/89] Bad logging, content is unsigned const char*, fixed it to use %s and not cast. --HG-- branch : gsoc2011-worldeditorqt --- .../src/plugins/world_editor/world_editor_misc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_misc.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_misc.cpp index dc1ae435f..f9eb7ce54 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_misc.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/world_editor/world_editor_misc.cpp @@ -50,7 +50,7 @@ void syntaxError(const char *filename, xmlNodePtr xmlNode, const char *format, . strcpy(buffer, "Unknown error"); } - nlerror("(%s), node (%s), line (%d) :\n%s", filename, xmlNode->name, (int)xmlNode->content, buffer); + nlerror("(%s), node (%s), line (%s) :\n%s", filename, xmlNode->name, xmlNode->content, buffer); } bool getPropertyString(std::string &result, const char *filename, xmlNodePtr xmlNode, const char *propName)