Changed: #1302 Added "unload primitive" and "unload landscape" undo command. Update doxygen comments.

This commit is contained in:
dnk-88 2011-08-22 21:53:23 +03:00
parent 55f0a2ad09
commit 433b7dde91
14 changed files with 293 additions and 42 deletions

View file

@ -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)];

View file

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

View file

@ -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;
};
/*

View file

@ -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())));
}

View file

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

View file

@ -33,6 +33,7 @@
// Qt includes
#include <QContextMenuEvent>
#include <QMessageBox>
#include <QApplication>
#include <QtGui/QMenu>
#include <QtGui/QFileDialog>
@ -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<Node *>(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();

View file

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

View file

@ -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 <nel/misc/debug.h>
#include <nel/ligo/ligo_config.h>
// Qt includes
#include <QtCore/QSettings>
@ -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<std::string> &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()));
}

View file

@ -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<LandscapeNode *>(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<RootPrimitiveNode *>(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<QGraphicsItem *> &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<QGraphicsItem *> &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<QGraphicsItem *> &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<QGraphicsItem *> &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<QGraphicsItem *> &ite
m_redoPolygons(polygons),
m_undoPolygons(polygonsFromItems(items))
{
setText("Change shape");
setText(QObject::tr("Change shape"));
}
ShapeWorldItemsCommand::~ShapeWorldItemsCommand()

View file

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

View file

@ -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<AbstractWorldItem *>(item);
m_worldItems.removeOne(worldItem);
delete item;
}

View file

@ -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<QGraphicsItem *> &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<QGraphicsItem *> &selected, const QList<QGraphicsItem *> &deselected);
protected:
@ -102,6 +118,7 @@ private:
qreal m_firstPickX, m_firstPickY, m_angle;
QList<QGraphicsItem *> m_selectedItems;
QList<QGraphicsItem *> m_selectedPoints;
QList<AbstractWorldItem *> m_worldItems;
QList<QPolygonF> m_polygons;
bool m_editedSelectedItems, m_firstSelection;
uint m_lastPickedPrimitive;

View file

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

View file

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