Changed: #1301 Experiments with undo\redo and QGraphicsScene.

This commit is contained in:
dnk-88 2011-06-14 12:26:41 +03:00
parent 885b08bfcc
commit 4a47857f09
11 changed files with 209 additions and 20 deletions

View file

@ -36,6 +36,35 @@
namespace LandscapeEditor 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 @class PixmapDatabase
@brief PixmapDatabase contains the image database @brief PixmapDatabase contains the image database

View file

@ -17,6 +17,7 @@
// Project includes // Project includes
#include "landscape_actions.h" #include "landscape_actions.h"
#include "builder_zone.h"
// NeL includes // NeL includes
#include <nel/misc/debug.h> #include <nel/misc/debug.h>
@ -25,4 +26,34 @@
namespace LandscapeEditor 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 */ } /* namespace LandscapeEditor */

View file

@ -19,13 +19,35 @@
#define LANDSCAPE_ACTIONS_H #define LANDSCAPE_ACTIONS_H
// Project includes // Project includes
#include "builder_zone.h"
// NeL includes // NeL includes
// Qt includes // Qt includes
#include <QtGui/QUndoCommand>
#include <QtGui/QGraphicsScene>
#include <QtGui/QGraphicsPixmapItem>
namespace LandscapeEditor 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 */ } /* namespace LandscapeEditor */

View file

@ -33,7 +33,6 @@
#include <QtCore/QSettings> #include <QtCore/QSettings>
#include <QtGui/QFileDialog> #include <QtGui/QFileDialog>
#include <QtOpenGL/QGLWidget> #include <QtOpenGL/QGLWidget>
#include <QtGui/QGraphicsPixmapItem>
namespace LandscapeEditor namespace LandscapeEditor
{ {
@ -50,10 +49,9 @@ LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent)
m_ui.zoneListWidget->setZoneBuilder(m_zoneBuilder); m_ui.zoneListWidget->setZoneBuilder(m_zoneBuilder);
m_ui.zoneListWidget->updateUi(); 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->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(); createMenus();
createToolBars(); createToolBars();

View file

@ -27,6 +27,14 @@
</property> </property>
<item row="0" column="0"> <item row="0" column="0">
<widget class="LandscapeEditor::LandscapeView" name="graphicsView"> <widget class="LandscapeEditor::LandscapeView" name="graphicsView">
<property name="sceneRect">
<rectf>
<x>0.000000000000000</x>
<y>0.000000000000000</y>
<width>99999.000000000000000</width>
<height>99999.000000000000000</height>
</rectf>
</property>
<property name="dragMode"> <property name="dragMode">
<enum>QGraphicsView::NoDrag</enum> <enum>QGraphicsView::NoDrag</enum>
</property> </property>

View file

@ -17,22 +17,68 @@
// Project includes // Project includes
#include "landscape_scene.h" #include "landscape_scene.h"
#include "builder_zone.h"
#include "landscape_actions.h"
#include "list_zones_widget.h"
// NeL includes // NeL includes
#include <nel/misc/debug.h> #include <nel/misc/debug.h>
// Qt includes // Qt includes
#include <QtGui/QPainter>
#include <QtGui/QGraphicsPixmapItem>
namespace LandscapeEditor namespace LandscapeEditor
{ {
LandscapeScene::LandscapeScene(QObject *parent) LandscapeScene::LandscapeScene(QUndoStack *undoStack, ListZonesWidget *listZonesWidget, ZoneBuilder *zoneBuilder, QObject *parent)
: QGraphicsScene(parent) : QGraphicsScene(parent),
m_undoStack(undoStack),
m_listZonesWidget(listZonesWidget),
m_zoneBuilder(zoneBuilder)
{ {
m_cellSize = 160;
createBackgroundPixmap();
} }
LandscapeScene::~LandscapeScene() 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 */ } /* namespace LandscapeEditor */

View file

@ -23,18 +23,33 @@
// NeL includes // NeL includes
// Qt includes // Qt includes
#include <QGraphicsScene> #include <QtGui/QGraphicsScene>
#include <QtGui/QGraphicsSceneMouseEvent>
#include <QtGui/QUndoStack>
namespace LandscapeEditor namespace LandscapeEditor
{ {
class ZoneBuilder;
class ListZonesWidget;
class LandscapeScene : public QGraphicsScene class LandscapeScene : public QGraphicsScene
{ {
Q_OBJECT Q_OBJECT
public: public:
LandscapeScene(QObject *parent = 0); LandscapeScene(QUndoStack *undoStack, ListZonesWidget *listZonesWidget, ZoneBuilder *zoneBuilder, QObject *parent = 0);
virtual ~LandscapeScene(); virtual ~LandscapeScene();
protected:
void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent);
private:
void createBackgroundPixmap();
int m_cellSize;
ListZonesWidget *m_listZonesWidget;
QUndoStack *m_undoStack;
ZoneBuilder *m_zoneBuilder;
}; };
} /* namespace LandscapeEditor */ } /* namespace LandscapeEditor */

View file

@ -26,27 +26,52 @@
#include <nel/misc/debug.h> #include <nel/misc/debug.h>
// Qt includes // Qt includes
#include <QApplication>
namespace LandscapeEditor namespace LandscapeEditor
{ {
LandscapeView::LandscapeView(QWidget *parent) LandscapeView::LandscapeView(QWidget *parent)
: QGraphicsView(parent) : QGraphicsView(parent),
m_moveMouse(false)
{ {
setDragMode(ScrollHandDrag); setDragMode(ScrollHandDrag);
setTransformationAnchor(AnchorUnderMouse);
} }
LandscapeView::~LandscapeView() LandscapeView::~LandscapeView()
{ {
} }
void LandscapeView::wheelEvent(QWheelEvent *event) void LandscapeView::wheelEvent(QWheelEvent *event)
{ {
double numDegrees = event->delta() / 8.0; double numDegrees = event->delta() / 8.0;
double numSteps = numDegrees / 15.0; double numSteps = numDegrees / 15.0;
double factor = std::pow(1.125, numSteps); double factor = std::pow(1.125, numSteps);
scale(factor, factor); 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 */ } /* namespace LandscapeEditor */

View file

@ -36,12 +36,16 @@ public:
~LandscapeView(); ~LandscapeView();
protected: 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 Q_SLOTS:
private: private:
bool m_moveMouse;
}; /* class LandscapeView */ }; /* class LandscapeView */
} /* namespace LandscapeEditor */ } /* namespace LandscapeEditor */

View file

@ -17,7 +17,6 @@
// Project includes // Project includes
#include "list_zones_widget.h" #include "list_zones_widget.h"
#include "builder_zone.h"
#include "list_zones_model.h" #include "list_zones_model.h"
// NeL includes // NeL includes
@ -31,6 +30,7 @@
// Qt includes // Qt includes
#include <QtGui/QIcon> #include <QtGui/QIcon>
#include <QtCore/QModelIndex>
namespace LandscapeEditor namespace LandscapeEditor
{ {
@ -100,6 +100,16 @@ void ListZonesWidget::updateUi()
m_listZonesModel->rebuildModel(m_zoneBuilder->pixmapDatabase()); 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) void ListZonesWidget::setZoneBuilder(ZoneBuilder *zoneBuilder)
{ {
m_zoneBuilder = zoneBuilder; m_zoneBuilder = zoneBuilder;

View file

@ -20,6 +20,7 @@
// Project includes // Project includes
#include "ui_list_zones_widget.h" #include "ui_list_zones_widget.h"
#include "builder_zone.h"
// NeL includes // NeL includes
@ -27,7 +28,6 @@
namespace LandscapeEditor namespace LandscapeEditor
{ {
class ZoneBuilder;
class ListZonesModel; class ListZonesModel;
/** /**
@ -45,6 +45,7 @@ public:
void updateUi(); void updateUi();
void setZoneBuilder(ZoneBuilder *zoneBuilder); void setZoneBuilder(ZoneBuilder *zoneBuilder);
LigoData currentLigoData() const;
Q_SIGNALS: Q_SIGNALS:
private Q_SLOTS: private Q_SLOTS: